Browse Source

Merge upstream version 4.20, import Debian version 4.20-1

Michael Piefel 17 years ago
parent
commit
64e579ca5c
60 changed files with 2371 additions and 2209 deletions
  1. 84 0
      ChangeLog
  2. 1 1
      LEGAL.NOTICE
  3. 1 11
      MAINT
  4. 1 1
      Makefile.in
  5. 1 1
      README
  6. 6 0
      config.h.in
  7. 5 3
      configure
  8. 3 3
      configure.in
  9. 2 2
      debian/copyright-prolog
  10. 1 0
      debian/file.install
  11. 332 268
      doc/file.man
  12. 20 0
      doc/libmagic.man
  13. 231 207
      doc/magic.man
  14. 0 805
      ltcf-c.sh
  15. 1 1
      magic/Localstuff
  16. 3 3
      magic/Magdir/animation
  17. 1 1
      magic/Magdir/archive
  18. 11 4
      magic/Magdir/audio
  19. 2 2
      magic/Magdir/c-lang
  20. 1 1
      magic/Magdir/commands
  21. 3 0
      magic/Magdir/console
  22. 0 4
      magic/Magdir/database
  23. 2 1
      magic/Magdir/editors
  24. 2 1
      magic/Magdir/elf
  25. 290 79
      magic/Magdir/filesystems
  26. 0 3
      magic/Magdir/images
  27. 1 1
      magic/Magdir/mathematica
  28. 1 1
      magic/Magdir/mime
  29. 2 2
      magic/Magdir/mips
  30. 2 2
      magic/Magdir/misctools
  31. 15 12
      magic/Magdir/msdos
  32. 1 1
      magic/Magdir/os2
  33. 14 6
      magic/Magdir/perl
  34. 2 1
      magic/Magdir/sgml
  35. 15 4
      magic/Magdir/sql
  36. 14 14
      magic/Magdir/tex
  37. 1 1
      magic/Magdir/tgif
  38. 6 0
      magic/Magdir/varied.out
  39. 1 1
      magic/Magdir/varied.script
  40. 1 1
      magic/Magdir/wordprocessors
  41. 20 9
      magic/magic.mime
  42. 1 1
      magic/magic2mime
  43. 427 117
      src/apprentice.c
  44. 1 1
      src/apptype.c
  45. 15 10
      src/ascmagic.c
  46. 26 19
      src/compress.c
  47. 35 5
      src/file.c
  48. 133 113
      src/file.h
  49. 1 1
      src/fsmagic.c
  50. 99 33
      src/funcs.c
  51. 1 1
      src/is_tar.c
  52. 8 33
      src/magic.c
  53. 20 11
      src/magic.h
  54. 1 1
      src/names.h
  55. 8 2
      src/patchlevel.h
  56. 33 19
      src/print.c
  57. 4 4
      src/readelf.c
  58. 453 305
      src/softmagic.c
  59. 1 71
      src/tar.h
  60. 4 4
      src/test.c

+ 84 - 0
ChangeLog

@@ -1,3 +1,87 @@
+
+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

+ 1 - 1
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.

+ 1 - 11
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

+ 1 - 1
Makefile.in

@@ -38,7 +38,7 @@ host_triplet = @host@
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
 	$(top_srcdir)/configure ChangeLog config.guess config.sub \
-	depcomp install-sh ltcf-c.sh ltmain.sh missing mkinstalldirs
+	depcomp install-sh ltmain.sh missing mkinstalldirs
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \

+ 1 - 1
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,

+ 6 - 0
config.h.in

@@ -66,6 +66,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 +85,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
 

+ 5 - 3
configure

@@ -1808,7 +1808,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=file
- VERSION=4.19
+ VERSION=4.20
 
 
 cat >>confdefs.h <<_ACEOF
@@ -20823,7 +20823,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 +22613,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

+ 3 - 3
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.20)
 AM_CONFIG_HEADER([config.h])
 AM_MAINTAINER_MODE
 
@@ -81,7 +81,7 @@ 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(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)

+ 2 - 2
debian/copyright-prolog

@@ -1,8 +1,8 @@
 This package was assembled by Michael Piefel <piefel@debian.org>
-sources from ftp://ftp.gw.com/mirrors/pub/unix/file/file-4.19.tar.gz .
+sources from ftp://ftp.astron.com/pub/file/file-4.20.tar.gz
 
 This package was previously maintained by Darren Stalder <torin@daft.com>,
-Bill Mitchell <mitchell@debian.org> and Nicolas Lichtmaier <nick@feedback.net.ar>.
+Bill Mitchell <mitchell@debian.org> and Nicolás Lichtmaier <nick@feedback.net.ar>.
 
 
 Upstream copyright and license information:

+ 1 - 0
debian/file.install

@@ -1,3 +1,4 @@
 etc/magic
+etc/magic.mime
 usr/bin
 usr/share/man/man1

+ 332 - 268
doc/file.man

@@ -1,77 +1,72 @@
-.TH FILE __CSECTION__ "March 2006" "Debian/GNU Linux" "Copyrighted but distributable"
-.\" $Id: file.man,v 1.59 2006/11/17 16:11:10 christos Exp $
-.SH NAME
-file
-\- determine file type
-.SH SYNOPSIS
-.B file
-[
-.B \-bchikLnNprsvz
-]
-[
-.B \-f
-.I namefile
-]
-[
-.B \-F
-.I separator
-]
-[
-.B \-m 
-.I magicfiles
-]
-.I file
-\&...
-.br
-.B file
-.B -C
-[
-.B \-m 
-magicfile ]
-.SH DESCRIPTION
+.\" $File: file.man,v 1.65 2007/01/25 21:05:46 christos Exp $
+.Dd January 8, 2007
+.Dt FILE __CSECTION__
+.Os
+.Sh NAME
+.Nm file
+.Nd determine file type
+.Sh SYNOPSIS
+.Nm
+.Op Fl bchikLnNprsvz
+.Op Fl f Ar namefile
+.Op Fl F Ar separator
+.Op Fl m Ar magicfiles
+.Ar file
+.Nm
+.Fl C
+.Op Fl m Ar magicfile
+.Sh DESCRIPTION
 This manual page documents version __VERSION__ of the
-.B file
+.Nm
 command.
-.PP
-.B File
+.Pp
+.Nm
 tests each argument in an attempt to classify it.
 There are three sets of tests, performed in this order:
 filesystem tests, magic number tests, and language tests.
 The
-.I first
+.Em first
 test that succeeds causes the file type to be printed.
-.PP
+.Pp
 The type printed will usually contain one of the words
-.B text
+.Em text
 (the file contains only
 printing characters and a few common control
 characters and is probably safe to read on an
-.SM ASCII
+.Dv ASCII
 terminal),
-.B executable
+.Em executable
 (the file contains the result of compiling a program
-in a form understandable to some \s-1UNIX\s0 kernel or another),
+in a form understandable to some 
+.Dv UNIX
+kernel or another),
 or
-.B data
-meaning anything else (data is usually `binary' or non-printable).
+.Em data
+meaning anything else (data is usually 
+.Sq binary
+or non-printable).
 Exceptions are well-known file formats (core files, tar archives)
 that are known to contain binary data.
 When adding local definitions to
-.IR /etc/magic ,
-.BR "preserve these keywords" .
+.Pa /etc/magic ,
+.Em "preserve these keywords" .
 People depend on knowing that all the readable files in a directory
-have the word ``text'' printed.
-Don't do as Berkeley did and change ``shell commands text''
-to ``shell script''.
+have the word 
+.Dq text
+printed.
+Don't do as Berkeley did and change 
+.Dq shell commands text
+to 
+.Dq shell script .
 Note that the file
-.I __MAGIC__
+.Pa __MAGIC__
 is built mechanically from a large number of small files in
 the subdirectory
-.I Magdir
+.Pa Magdir
 in the source distribution of this program.
-.PP
+.Pp
 The filesystem tests are based on examining the return from a
-.BR stat (2)
+.Xr stat 2
 system call.
 The program checks to see if the file is empty,
 or if it's some sort of special file.
@@ -80,38 +75,44 @@ Any known file types appropriate to the system you are running on
 implement them)
 are intuited if they are defined in
 the system header file
-.IR <sys/stat.h>  .
-.PP
+.In sys/stat.h .
+.Pp
 The magic number tests are used to check for files with data in
 particular fixed formats.
 The canonical example of this is a binary executable (compiled program)
-.I a.out
+.Dv a.out
 file, whose format is defined in 
-.I a.out.h
+.In elf.h ,
+.In a.out.h
 and possibly
-.I exec.h
+.In exec.h
 in the standard include directory.
-These files have a `magic number' stored in a particular place
-near the beginning of the file that tells the \s-1UNIX\s0 operating system
+These files have a 
+.Sq "magic number"
+stored in a particular place
+near the beginning of the file that tells the 
+.Dv UNIX operating system
 that the file is a binary executable, and which of several types thereof.
-The concept of `magic number' has been applied by extension to data files.
+The concept of a
+.Sq "magic number"
+has been applied by extension to data files.
 Any file with some invariant identifier at a small fixed
 offset into the file can usually be described in this way.
 The information identifying these files is read from
-.I /etc/magic
+.Pa /etc/magic
 and the compiled
 magic file
-.I __MAGIC__.mgc ,
+.Pa __MAGIC__.mgc ,
 or 
-.I __MAGIC__
-if the compile file does not exist. In addition
-.B file
+.Pa __MAGIC__
+if the compiled file does not exist. In addition
+.Nm
 will look in
-.I $HOME/.magic.mgc ,
+.Pa $HOME/.magic.mgc ,
 or
-.I $HOME/.magic
+.Pa $HOME/.magic
 for magic entries.
-.PP
+.Pp
 If a file does not match any of the entries in the magic file,
 it is examined to see if it seems to be a text file.
 ASCII, ISO-8859-x, non-ISO 8-bit extended-ASCII character sets
@@ -122,214 +123,253 @@ ranges and sequences of bytes that constitute printable text
 in each set.
 If a file passes any of these tests, its character set is reported.
 ASCII, ISO-8859-x, UTF-8, and extended-ASCII files are identified
-as ``text'' because they will be mostly readable on nearly any terminal;
-UTF-16 and EBCDIC are only ``character data'' because, while
+as 
+.Dq text
+because they will be mostly readable on nearly any terminal;
+UTF-16 and EBCDIC are only 
+.Dq character data
+because, while
 they contain text, it is text that will require translation
 before it can be read.
 In addition,
-.B file
+.Nm
 will attempt to determine other characteristics of text-type files.
 If the lines of a file are terminated by CR, CRLF, or NEL, instead
 of the Unix-standard LF, this will be reported.
 Files that contain embedded escape sequences or overstriking
 will also be identified.
-.PP
+.Pp
 Once
-.B file
+.Nm
 has determined the character set used in a text-type file,
 it will
 attempt to determine in what language the file is written.
 The language tests look for particular strings (cf
-.IR names.h )
+.In names.h
 that can appear anywhere in the first few blocks of a file.
 For example, the keyword
-.B .br
+.Em .br
 indicates that the file is most likely a
-.BR troff (1)
+.Xr troff 1
 input file, just as the keyword 
-.B struct
+.Em struct
 indicates a C program.
 These tests are less reliable than the previous
 two groups, so they are performed last.
 The language test routines also test for some miscellany
 (such as 
-.BR tar (1)
+.Xr tar 1
 archives).
-.PP
+.Pp
 Any file that cannot be identified as having been written
-in any of the character sets listed above is simply said to be ``data''.
-.SH OPTIONS
-.TP 8
-.B "\-b, \-\-brief"
+in any of the character sets listed above is simply said to be
+.Dq data .
+.Sh OPTIONS
+.Bl -tag -width indent
+.It Fl b , -brief
 Do not prepend filenames to output lines (brief mode).
-.TP 8
-.B "\-c, \-\-checking\-printout"
+.It Fl c , -checking-printout
 Cause a checking printout of the parsed form of the magic file.
-This is usually used in conjunction with 
-.B \-m
-to debug a new magic file before installing it.
-.TP 8
-.B "\-C, \-\-compile"
-Write a magic.mgc output file that contains a pre-parsed version of
-file.
-.TP 8
-.BI "\-f, \-\-files\-from" " namefile"
+This is usually used in conjunction with the
+.Fl m
+flag to debug a new magic file before installing it.
+.It Fl C , -compile
+Write a
+.Pa magic.mgc
+output file that contains a pre-parsed version of the magic file.
+.It Fl e , -exclude Ar testname
+Exclude the test named in
+.Ar testname
+from the list of tests made to determine the file type. Valid test names
+are:
+.Bl -tag -width
+.It apptype
+Check for
+.Dv EMX
+application type (only on EMX).
+.It ascii
+Check for various types of ascii files.
+.It compress
+Don't look for, or inside compressed files.
+.It elf
+Don't print elf details.
+.It fortran
+Don't look for fortran sequences inside ascii files.
+.It soft
+Don't consult magic files.
+.It tar
+Don't examine tar files.
+.It token
+Don't look for known tokens inside ascii files.
+.It troff
+Don't look for troff sequences inside ascii files.
+.El
+.It Fl f , -files-from Ar namefile
 Read the names of the files to be examined from 
-.I namefile
+.Ar namefile
 (one per line) 
 before the argument list.
 Either 
-.I namefile
+.Ar namefile
 or at least one filename argument must be present;
-to test the standard input, use ``\-'' as a filename argument.
-.TP 8
-.BI "\-F, \-\-separator" " separator"
+to test the standard input, use 
+.Sq -
+as a filename argument.
+.It Fl F , -separator Ar separator
 Use the specified string as the separator between the filename and the
-file result returned. Defaults to ``:''.
-.TP 8
-.B "\-h, \-\-no-dereference"
+file result returned. Defaults to 
+.Sq \&: .
+.It Fl h , -no-dereference
 option causes symlinks not to be followed
 (on systems that support symbolic links). This is the default if the
 environment variable
-.I POSIXLY_CORRECT
+.Dv POSIXLY_CORRECT
 is not defined.
-.TP 8
-.B "\-i, \-\-mime"
+.It Fl i , -mime
 Causes the file command to output mime type strings rather than the more
 traditional human readable ones. Thus it may say
-``text/plain; charset=us-ascii''
+.Dq text/plain; charset=us-ascii
 rather
-than ``ASCII text''.
+than
+.Dq ASCII text .
 In order for this option to work, file changes the way
 it handles files recognized by the command itself (such as many of the
 text file types, directories etc), and makes use of an alternative
-``magic'' file.
-(See ``FILES'' section, below).
-.TP 8
-.B "\-k, \-\-keep\-going"
+.Dq magic
+file.
+(See
+.Dq FILES
+section, below).
+.It Fl k , -keep-going
 Don't stop at the first match, keep going. Subsequent matches will be
-prepended by ``\\012\- ''. (If you want a newline, see ``\-r'' option.)
-.TP 8
-.B "\-L, \-\-dereference"
+prepended by
+.Dq "\[rs]012\- ".
+(If you want a newline, see 
+.Dq "\-r"
+option.)
+.It Fl L , -dereference
 option causes symlinks to be followed, as the like-named option in
-.BR ls (1)
+.Xr ls 1
 (on systems that support symbolic links).
 This is the default if the environment variable
-.I POSIXLY_CORRECT
+.Dv POSIXLY_CORRECT
 is defined.
-.TP 8
-.BI "\-m, \-\-magic\-file" " list"
+.It Fl m , -magic-file Ar list
 Specify an alternate list of files containing magic numbers.
 This can be a single file, or a colon-separated list of files.
 If a compiled magic file is found alongside, it will be used instead.
-With the \-i or \-\-mime option, the program adds ".mime" to each file name.
-.TP 8
-.B "\-n, \-\-no\-buffer"
+With the 
+.Fl i
+or 
+.Fl "mime"
+option, the program adds
+.Dq .mime
+to each file name.
+.It Fl n , -no-buffer
 Force stdout to be flushed after checking each file.
 This is only useful if checking a list of files.
 It is intended to be used by programs that want filetype output from a pipe.
-.TP 8
-.B "\-N, \-\-no\-pad"
+.It Fl N , -no-pad
 Don't pad filenames so that they align in the output.
-.TP 8
-.B "\-p, \-\-preserve\-date"
+.It Fl p , -preserve-date
 On systems that support
-.BR utime (2)
+.Xr utime 2
 or
-.BR utimes(2),
+.Xr utimes 2 ,
 attempt to preserve the access time of files analyzed, to pretend that
-.BR file (2)
+.Nm
 never read them.
-.TP 8
-.B "\-r, \-\-raw"
+.It Fl r , -raw
 Don't translate unprintable characters to \eooo.
 Normally
-.B file
+.Nm
 translates unprintable characters to their octal representation.
-.TP 8
-.B "\-s, \-\-special\-files"
+.It Fl s , -special-files
 Normally,
-.B file
+.Nm
 only attempts to read and determine the type of argument files which
-.BR stat (2)
+.Xr stat 2
 reports are ordinary files.
 This prevents problems, because reading special files may have peculiar
 consequences.
 Specifying the
-.BR \-s
+.Fl s
 option causes
-.B file
+.Nm
 to also read argument files which are block or character special files.
 This is useful for determining the filesystem types of the data in raw
 disk partitions, which are block special files.
 This option also causes
-.B file
+.Nm
 to disregard the file size as reported by
-.BR stat (2)
+.Xr stat 2
 since on some systems it reports a zero size for raw disk partitions.
-.TP 8
-.B "\-v, \-\-version"
+.It Fl v , -version
 Print the version of the program and exit.
-.TP 8
-.B "\-z, \-\-uncompress"
+.It Fl z , -uncompress
 Try to look inside compressed files.
-.B "\-0, \-\-print0"
-Output a null character ('\0') after the end of the filename. Nice to
-.BR cut (1)
+.It Fl 0 , -print0
+Output a null character
+.Sq \e0
+after the end of the filename. Nice to
+.Xr cut 1
 the output. This does not affect the separator which is still printed.
-.TP 8
-.B "\-\-help"
+.It Fl -help
 Print a help message and exit.
-.SH FILES
-.TP
-.I __MAGIC__.mgc
+.El
+.Sh FILES
+.Bl -tag -width __MAGIC__.mime.mgc -compact
+.It Pa __MAGIC__.mgc
 Default compiled list of magic numbers
-.TP
-.I __MAGIC__
+.It Pa __MAGIC__
 Default list of magic numbers
-.TP
-.I __MAGIC__.mime.mgc
+.It Pa __MAGIC__.mime.mgc
 Default compiled list of magic numbers, used to output mime types when
-the -i option is specified.
-.TP
-.I __MAGIC__.mime
-Default list of magic numbers, used to output mime types when the -i option
-is specified.
-
-.SH ENVIRONMENT
+the 
+.Fl i
+option is specified.
+.It Pa __MAGIC__.mime
+Default list of magic numbers, used to output mime types when the 
+.Fl i
+option is specified.
+.El
+.Sh ENVIRONMENT
 The environment variable
-.B MAGIC
+.Dv MAGIC
 can be used to set the default magic number file name.
 If that variable is set, then
-.B file
+.Nm
 will not attempt to open
-.BR $HOME/.magic .
-.B file
-adds ".mime" and/or ".mgc" to the value of this variable as appropriate.
+.Pa $HOME/.magic .
+.Nm
+adds
+.Dq .mime
+and/or
+.Dq .mgc
+to the value of this variable as appropriate.
 However,
-.B file
+.Pa file
 has to exist in order for
-.BR file .mime
+.Pa file.mime
 to be considered.
 The environment variable
-.B POSIXLY_CORRECT
+.Dv POSIXLY_CORRECT
 controls (on systems that support symbolic links), if
-.B file
+.Nm
 will attempt to follow symlinks or not. If set, then
-.B file
+.Nm
 follows symlink, otherwise it does not. This is also controlled
 by the
-.B L
+.Fl L
 and
-.B h
+.Fl h
 options.
-.SH SEE ALSO
-.BR magic (__FSECTION__)
-\- description of magic file format.
-.br
-.BR strings (1), " od" (1), " hexdump(1)"
-\- tools for examining non-textfiles.
-.SH STANDARDS CONFORMANCE
+.Sh SEE ALSO
+.Xr magic __FSECTION__ ,
+.Xr strings 1 ,
+.Xr od 1 ,
+.Xr hexdump 1
+.Sh STANDARDS CONFORMANCE
 This program is believed to exceed the System V Interface Definition
 of FILE(CMD), as near as one can determine from the vague language
 contained therein. 
@@ -337,60 +377,68 @@ Its behavior is mostly compatible with the System V program of the same name.
 This version knows more magic, however, so it will produce
 different (albeit more accurate) output in many cases. 
 .\" URL: http://www.opengroup.org/onlinepubs/009695399/utilities/file.html
-.PP
+.Pp
 The one significant difference 
 between this version and System V
 is that this version treats any white space
 as a delimiter, so that spaces in pattern strings must be escaped.
 For example,
-.br
+.Bd -literal -offset indent 
 >10	string	language impress\ 	(imPRESS data)
-.br
+.Ed
+.Pp
 in an existing magic file would have to be changed to
-.br
+.Bd -literal -offset indent 
 >10	string	language\e impress	(imPRESS data)
-.br
+.Ed
+.Pp
 In addition, in this version, if a pattern string contains a backslash,
 it must be escaped.
 For example
-.br
+.Bd -literal -offset indent 
 0	string		\ebegindata	Andrew Toolkit document
-.br
+.Ed
+.Pp
 in an existing magic file would have to be changed to
-.br
+.Bd -literal -offset indent 
 0	string		\e\ebegindata	Andrew Toolkit document
-.br
-.PP
+.Ed
+.Pp
 SunOS releases 3.2 and later from Sun Microsystems include a
-.BR file (1)
+.Nm 
 command derived from the System V one, but with some extensions.
 My version differs from Sun's only in minor ways.
-It includes the extension of the `&' operator, used as,
+It includes the extension of the 
+.Sq &
+operator, used as,
 for example,
-.br
+.Bd -literal -offset indent 
 >16	long&0x7fffffff	>0		not stripped
-.SH MAGIC DIRECTORY
+.Ed
+.Sh MAGIC DIRECTORY
 The magic file entries have been collected from various sources,
 mainly USENET, and contributed by various authors.
 Christos Zoulas (address below) will collect additional
 or corrected magic file entries.
 A consolidation of magic file entries 
 will be distributed periodically.
-.PP
+.Pp
 The order of entries in the magic file is significant.
 Depending on what system you are using, the order that
 they are put together may be incorrect.
-.SH EXAMPLES
-.nf
+.Sh EXAMPLES
+.Bd -literal -offset indent 
 $ file file.c file /dev/{wd0a,hda}
 file.c:   C program text
 file:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
           dynamically linked (uses shared libs), stripped
 /dev/wd0a: block special (0/0)
 /dev/hda: block special (3/0)
+
 $ file -s /dev/wd0{b,d}
 /dev/wd0b: data
 /dev/wd0d: x86 boot sector
+
 $ file -s /dev/hda{,1,2,3,4,5,6,7,8,9,10}
 /dev/hda:   x86 boot sector
 /dev/hda1:  Linux/i386 ext2 filesystem
@@ -407,139 +455,155 @@ $ file -s /dev/hda{,1,2,3,4,5,6,7,8,9,10}
 $ file -i file.c file /dev/{wd0a,hda}
 file.c:      text/x-c
 file:        application/x-executable, dynamically linked (uses shared libs),
-not stripped
+	     not stripped
 /dev/hda:    application/x-not-regular-file
 /dev/wd0a:   application/x-not-regular-file
 
-.fi
-.SH HISTORY
+.Ed
+.Sh HISTORY
 There has been a 
-.B file
-command in every \s-1UNIX\s0 since at least Research Version 4
+.Nm 
+command in every 
+.Dv UNIX since at least Research Version 4
 (man page dated November, 1973).
 The System V version introduced one significant major change:
 the external list of magic number types.
 This slowed the program down slightly but made it a lot more flexible.
-.PP
+.Pp
 This program, based on the System V version,
 was written by Ian Darwin <ian@darwinsys.com>
 without looking at anybody else's source code.
-.PP
+.Pp
 John Gilmore revised the code extensively, making it better than
 the first version.
 Geoff Collyer found several inadequacies
 and provided some magic file entries.
 Contributions by the `&' operator by Rob McMahon, cudcv@warwick.ac.uk, 1989.
-.PP
+.Pp
 Guy Harris, guy@netapp.com, made many changes from 1993 to the present.
-.PP
+.Pp
 Primary development and maintenance from 1990 to the present by
 Christos Zoulas (christos@astron.com).
-.PP
+.Pp
 Altered by Chris Lowth, chris@lowth.com, 2000:
-Handle the ``-i'' option to output mime type strings and using an alternative
+Handle the 
+.Fl i
+option to output mime type strings and using an alternative
 magic file and internal logic.
-.PP
+.Pp
 Altered by Eric Fischer (enf@pobox.com), July, 2000,
 to identify character codes and attempt to identify the languages
 of non-ASCII files.
-.PP
+.Pp
 The list of contributors to the "Magdir" directory (source for the
-.I __MAGIC__
+.Pa __MAGIC__
 file) is too long to include here.
 You know who you are; thank you.
-.SH LEGAL NOTICE
+.Sh LEGAL NOTICE
 Copyright (c) Ian F. Darwin, Toronto, Canada, 1986-1999.
 Covered by the standard Berkeley Software Distribution copyright; see the file
 LEGAL.NOTICE in the source distribution.
-.PP
+.Pp
 The files
-.I tar.h
+.Dv tar.h
 and
-.I is_tar.c
+.Dv is_tar.c
 were written by John Gilmore from his public-domain
-.B tar
+.Xr tar 1
 program, and are not covered by the above license.
-.SH BUGS
+.Sh BUGS
 There must be a better way to automate the construction of the Magic
 file from all the glop in Magdir.
 What is it?
-Better yet, the magic file should be compiled into binary (say,
-.BR ndbm (3)
-or, better yet, fixed-length
-.SM ASCII
-strings for use in heterogenous network environments) for faster startup.
-Then the program would run as fast as the Version 7 program of the same name,
-with the flexibility of the System V version.
-.PP
-.B File
+.\" Compilation support has been done
+.\" Better yet, the magic file should be compiled into binary (say,
+.\" .Xr ndbm 3
+.\" or, better yet, fixed-length
+.\" .Dv ASCII
+.\" strings for use in heterogenous network environments) for faster startup.
+.\" Then the program would run as fast as the Version 7 program of the same
+.\" name, with the flexibility of the System V version.
+.Pp
+.Nm
 uses several algorithms that favor speed over accuracy,
 thus it can be misled about the contents of
 text
 files.
-.PP
-The support for
-text
-files (primarily for programming languages)
+.Pp
+The support for text files (primarily for programming languages)
 is simplistic, inefficient and requires recompilation to update.
-.PP
-There should be an ``else'' clause to follow a series of continuation lines.
-.PP
-The magic file and keywords should have regular expression support.
+.\" Else support has been done
+.\" There should be an
+.\" .Dv else
+.\" clause to follow a series of continuation lines.
+.\" .Pp
+.\" Regular expression support has been done
+.\" The magic file and keywords should have regular expression support.
 Their use of
-.SM "ASCII TAB"
+.Dv ASCII TAB
 as a field delimiter is ugly and makes
 it hard to edit the files, but is entrenched.
-.PP
+.Pp
 It might be advisable to allow upper-case letters in keywords
 for e.g.,
-.BR troff (1)
+.Xr troff 1
 commands vs man page macros.
 Regular expression support would make this easy.
-.PP
-The program doesn't grok \s-2FORTRAN\s0.
-It should be able to figure \s-2FORTRAN\s0 by seeing some keywords which 
+.Pp
+The program doesn't grok 
+.Dv FORTRAN .
+It should be able to figure
+.Dv FORTRAN
+by seeing some keywords which 
 appear indented at the start of line.
 Regular expression support would make this easy.
-.PP
+.Pp
 The list of keywords in 
-.I ascmagic
+.Dv ascmagic
 probably belongs in the Magic file.
-This could be done by using some keyword like `*' for the offset value.
-.PP
-Another optimization would be to sort
-the magic file so that we can just run down all the
-tests for the first byte, first word, first long, etc, once we
-have fetched it.
+This could be done by using some keyword like 
+.Sq *
+for the offset value.
+.Pp
+.\" Sorting has been done.
+.\" Another optimization would be to sort
+.\" the magic file so that we can just run down all the
+.\" tests for the first byte, first word, first long, etc, once we
+.\" have fetched it.
 Complain about conflicts in the magic file entries.
 Make a rule that the magic entries sort based on file offset rather
 than position within the magic file?
-.PP
+.Pp
 The program should provide a way to give an estimate 
-of ``how good'' a guess is.
-We end up removing guesses (e.g. ``From '' as first 5 chars of file) because
-they are not as good as other guesses (e.g. ``Newsgroups:'' versus
-``Return-Path:'').
+of 
+.Dq how good
+a guess is.
+We end up removing guesses (e.g. 
+.Dq From\ 
+as first 5 chars of file) because
+they are not as good as other guesses (e.g. 
+.Dq Newsgroups:
+versus
+.Dq Return-Path:
+).
 Still, if the others don't pan out, it should be possible to use the
 first guess.  
-.PP
+.Pp
 This program is slower than some vendors' file commands.
 The new support for multiple character codes makes it even slower.
-.PP
+.Pp
 This manual page, and particularly this section, is too long.
-.SH RETURN CODE
-.B file
-almost always returns 0. It returns a different if it cannot open a file.
-.SH AVAILABILITY
+.Sh RETURN CODE
+.Nm
+almost always returns 0. It returns a different code if it cannot open a file.
+.Sh AVAILABILITY
 You can obtain the original author's latest version by anonymous FTP
 on
-.B ftp.astron.com
+.Dv ftp.astron.com
 in the directory
-.I /pub/file/file-X.YZ.tar.gz
-.PP
-This
-.B Debian
-version adds a number of new magix entries. It can be
-obtained from every site carrying a
-.B Debian
-distribution (ftp.debian.org and mirrors).
+.Dv /pub/file/file-X.YZ.tar.gz
+.Pp
+This Debian version adds a number of new magix entries. It can be
+obtained from every site carrying a Debian distribution (that is
+.Dv ftp.debian.org
+and mirrors).

+ 20 - 0
doc/libmagic.man

@@ -104,6 +104,26 @@ Don't translate unprintable characters to a \eooo octal representation.
 .It Dv MAGIC_ERROR
 Treat operating system errors while trying to open files and follow symlinks
 as real errors, instead of printing them in the magic buffer.
+.It Dv MAGIC_NO_CHECK_APPTYPE
+Check for
+.Dv EMX
+application type (only on EMX).
+.It Dv MAGIC_NO_CHECK_ASCII
+Check for various types of ascii files.
+.It Dv MAGIC_NO_CHECK_COMPRESS
+Don't look for, or inside compressed files.
+.It Dv MAGIC_NO_CHECK_ELF
+Don't print elf details.
+.It Dv MAGIC_NO_CHECK_FORTRAN
+Don't look for fortran sequences inside ascii files.
+.It Dv MAGIC_NO_CHECK_SOFT
+Don't consult magic files.
+.It Dv MAGIC_NO_CHECK_TAR
+Don't examine tar files.
+.It Dv MAGIC_NO_CHECK_TOKENS
+Don't look for known tokens inside ascii files.
+.It Dv MAGIC_NO_CHECK_TROFF
+Don't look for troff sequences inside ascii files.
 .El
 .Pp
 The

+ 231 - 207
doc/magic.man

@@ -1,413 +1,437 @@
-.TH MAGIC __FSECTION__ "Public Domain"
+.\" $File: magic.man,v 1.36 2007/01/10 22:56:49 christos Exp $
+.Dd January 10, 2007
+.Dt MAGIC __FSECTION__
+.Os
 .\" install as magic.4 on USG, magic.5 on V7 or Berkeley systems.
-.SH NAME
-magic \- file command's magic number file
-.SH DESCRIPTION
+.Sh NAME
+.Nm magic
+.Nd file command's magic number file
+.Sh DESCRIPTION
 This manual page documents the format of the magic file as
 used by the
-.BR file (__CSECTION__)
+.Xr file __CSECTION__
 command, version __VERSION__.
 The
-.BR file
+.Xr file __CSECTION__
 command identifies the type of a file using,
 among other tests,
 a test for whether the file begins with a certain
-.IR "magic number" .
+.Dq "magic number" .
 The file
-.I __MAGIC__
+.Pa __MAGIC__
 specifies what magic numbers are to be tested for,
 what message to print if a particular magic number is found,
 and additional information to extract from the file.
-.PP
+.Pp
 Each line of the file specifies a test to be performed.
 A test compares the data starting at a particular offset
 in the file with a 1-byte, 2-byte, or 4-byte numeric value or
 a string.
 If the test succeeds, a message is printed.
 The line consists of the following fields:
-.IP offset \w'message'u+2n
+.Bl -tag -width ".Dv message"
+.It Dv offset
 A number specifying the offset, in bytes, into the file of the data
 which is to be tested.
-.IP type
+.It Dv type
 The type of the data to be tested.
 The possible values are:
-.RS
-.IP byte \w'message'u+2n
+.Bl -tag -width ".Dv lestring16"
+.It Dv byte
 A one-byte value.
-.IP short
+.It Dv short
 A two-byte value (on most systems) in this machine's native byte order.
-.IP long
+.It Dv long
 A four-byte value (on most systems) in this machine's native byte order.
-.IP quad
+.It Dv quad
 An eight-byte value (on most systems) in this machine's native byte order.
-.IP string
+.It Dv string
 A string of bytes.
 The string type specification can be optionally followed
 by /[Bbc]*.
-The ``B'' flag compacts whitespace in the target, which must
+The 
+.Dq B
+flag compacts whitespace in the target, which must
 contain at least one whitespace character.
 If the magic has
-.I n
+.Dv n
 consecutive blanks, the target needs at least
-.I n
+.Dv n
 consecutive blanks to match.
-The ``b'' flag treats every blank in the target as an optional blank.
-Finally the ``c'' flag, specifies case insensitive matching: lowercase
+The 
+.Dq b
+flag treats every blank in the target as an optional blank.
+Finally the
+.Dq c
+flag, specifies case insensitive matching: lowercase
 characters in the magic match both lower and upper case characters in the
 target, whereas upper case characters in the magic, only much uppercase
 characters in the target.
-.IP pstring
+.It Dv pstring
 A pascal style string where the first byte is interpreted as the an
 unsigned length. The string is not NUL terminated.
-.IP date
+.It Dv date
 A four-byte value interpreted as a UNIX date.
-.IP qdate
+.It Dv qdate
 A eight-byte value interpreted as a UNIX date.
-.IP ldate
+.It Dv ldate
 A four-byte value interpreted as a UNIX-style date, but interpreted as
 local time rather than UTC.
-.IP qldate
+.It Dv qldate
 An eight-byte value interpreted as a UNIX-style date, but interpreted as
 local time rather than UTC.
-.IP beshort
+.It Dv beshort
 A two-byte value (on most systems) in big-endian byte order.
-.IP belong
+.It Dv belong
 A four-byte value (on most systems) in big-endian byte order.
-.IP bequad
+.It Dv bequad
 An eight-byte value (on most systems) in big-endian byte order.
-.IP bedate
+.It Dv bedate
 A four-byte value (on most systems) in big-endian byte order,
 interpreted as a Unix date.
-.IP beqdate
+.It Dv beqdate
 An eight-byte value (on most systems) in big-endian byte order,
 interpreted as a Unix date.
-.IP beldate
+.It Dv beldate
 A four-byte value (on most systems) in big-endian byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
-.IP beqldate
+.It Dv beqldate
 An eight-byte value (on most systems) in big-endian byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
-.IP bestring16
+.It Dv bestring16
 A two-byte unicode (UCS16) string in big-endian byte order.
-.IP leshort
+.It Dv leshort
 A two-byte value (on most systems) in little-endian byte order.
-.IP lelong
+.It Dv lelong
 A four-byte value (on most systems) in little-endian byte order.
-.IP lequad
+.It Dv lequad
 An eight-byte value (on most systems) in little-endian byte order.
-.IP ledate
+.It Dv ledate
 A four-byte value (on most systems) in little-endian byte order,
 interpreted as a UNIX date.
-.IP leqdate
+.It Dv leqdate
 An eight-byte value (on most systems) in little-endian byte order,
 interpreted as a UNIX date.
-.IP leldate
+.It Dv leldate
 A four-byte value (on most systems) in little-endian byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
-.IP leqldate
+.It Dv leqldate
 An eight-byte value (on most systems) in little-endian byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
-.IP lestring16
+.It Dv lestring16
 A two-byte unicode (UCS16) string in little-endian byte order.
-.IP melong
+.It Dv melong
 A four-byte value (on most systems) in middle-endian (PDP-11) byte order.
-.IP medate
+.It Dv medate
 A four-byte value (on most systems) in middle-endian (PDP-11) byte order,
 interpreted as a UNIX date.
-.IP meldate
+.It Dv meldate
 A four-byte value (on most systems) in middle-endian (PDP-11) byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
-.IP regex
+.It Dv regex
 A regular expression match in extended POSIX regular expression syntax
 (much like egrep).
-The type specification can be optionally followed by
-.B /c
-for case-insensitive matches.
-The regular expression is always
-tested against the first
-.B N
+The type specification can be optionally followed by /[cse]*.
+The 
+.Dq c
+flag makes the match case insensitive, while the
+.Dq s
+or
+.Dq e
+flags update the offset to the starting or ending offsets of the
+match (only one should be used).
+By default, regex does not update the offset.
+The regular expression is always tested against the first
+.Dv N
 lines, where
-.B N
+.Dv N
 is the given offset, thus it
 is only useful for (single-byte encoded) text.
-.B ^
+.Dv ^
 and
-.B $
+.Dv $
 will match the beginning and end of individual lines, respectively,
 not beginning and end of file.
-.IP search
+.It Dv search
 A literal string search starting at the given offset. It must be followed by
-.B /<number>
+.Dv /<number>
 which specifies how many matches shall be attempted (the range).
 This is suitable for searching larger binary expressions with variable
 offsets, using
-.B \e
+.Dv \e
 escapes for special characters.
-.RE
-.PP
+.It Dv default 
+This is intended to be used with the text
+.Dv x
+(which is always true) and a message that is to be used if there are
+no other matches.
+.El
+.El
+.Pp
 The numeric types may optionally be followed by
-.B &
+.Dv &
 and a numeric value,
 to specify that the value is to be AND'ed with the
 numeric value before any comparisons are done.
 Prepending a
-.B u
+.Dv u
 to the type indicates that ordered comparisons should be unsigned.
-.IP test
+.Bl -tag -width ".Dv message"
+.It Dv test
 The value to be compared with the value from the file.
 If the type is
 numeric, this value
 is specified in C form; if it is a string, it is specified as a C string
 with the usual escapes permitted (e.g. \en for new-line).
-.IP
+.Pp
 Numeric values
 may be preceded by a character indicating the operation to be performed.
 It may be
-.BR = ,
+.Dv = ,
 to specify that the value from the file must equal the specified value,
-.BR < ,
+.Dv < ,
 to specify that the value from the file must be less than the specified
 value,
-.BR > ,
+.Dv > ,
 to specify that the value from the file must be greater than the specified
 value,
-.BR & ,
+.Dv & ,
 to specify that the value from the file must have set all of the bits
 that are set in the specified value,
-.BR ^ ,
+.Dv ^ ,
 to specify that the value from the file must have clear any of the bits
 that are set in the specified value, or
-.BR ~ ,
+.Dv ~ ,
 the value specified after is negated before tested.
-.BR x ,
+.Dv x ,
 to specify that any value will match.
 If the character is omitted, it is assumed to be
-.BR = .
+.Dv = .
 For all tests except
-.B string
+.Em string
 and
-.B regex,
+.Em regex,
 operation
-.BR !
+.Dv !
 specifies that the line matches if the test does
-.B not
+.Em not
 succeed.
-.IP
+.Pp
 Numeric values are specified in C form; e.g.
-.B 13
+.Dv 13
 is decimal,
-.B 013
+.Dv 013
 is octal, and
-.B 0x13
+.Dv 0x13
 is hexadecimal.
-.IP
+.Pp
 For string values, the byte string from the
 file must match the specified byte string.
 The operators
-.BR = ,
-.B <
+.Dv = ,
+.Dv <
 and
-.B >
+.Dv >
 (but not
-.BR & )
+.Dv & )
 can be applied to strings.
 The length used for matching is that of the string argument
 in the magic file.
 This means that a line can match any string, and
 then presumably print that string, by doing
-.B >\e0
+.Em >\e0
 (because all strings are greater than the null string).
-.IP message
+.Pp
+The special test
+.Em x
+always evaluates to true.
+.Dv message
 The message to be printed if the comparison succeeds.  If the string
 contains a
-.BR printf (3)
+.Xr printf 3
 format specification, the value from the file (with any specified masking
 performed) is printed using the message as the format string.
-.PP
+If the string begins with ``\\b'', the message printed is the
+remainder of the string with no whitespace added before it: multiple
+matches are normally separated by a single space.
+.El
+.Pp
 Some file formats contain additional information which is to be printed
 along with the file type or need additional tests to determine the true
 file type.
 These additional tests are introduced by one or more
-.B >
+.Em >
 characters preceding the offset.
 The number of
-.B >
+.Em >
 on the line indicates the level of the test; a line with no
-.B >
+.Em >
 at the beginning is considered to be at level 0.
 Tests are arranged in a tree-like hierarchy:
 If a the test on a line at level
-.IB n
+.Em n
 succeeds, all following tests at level
-.IB n+1
+.Em n+1
 are performed, and the messages printed if the tests succeed, untile a line
 with level
-.IB n
+.Em n
 (or less) appears.
 For more complex files, one can use empty messages to get just the
 "if/then" effect, in the following way:
-.sp
-.nf
-    0      string   MZ
-    >0x18  leshort  <0x40   MS-DOS executable
-    >0x18  leshort  >0x3f   extended PC executable (e.g., MS Windows)
-.fi
-.PP
+.Bd -literal -offset indent 
+0      string   MZ
+>0x18  leshort  <0x40   MS-DOS executable
+>0x18  leshort  >0x3f   extended PC executable (e.g., MS Windows)
+.Ed
+.Pp
 Offsets do not need to be constant, but can also be read from the file
 being examined.
 If the first character following the last
-.B >
+.Em >
 is a
-.B (
+.Em (
 then the string after the parenthesis is interpreted as an indirect offset.
 That means that the number after the parenthesis is used as an offset in
 the file.
 The value at that offset is read, and is used again as an offset
 in the file.
 Indirect offsets are of the form:
-.BI (( x [.[bslBSL]][+\-][ y ]).
+.Em (( x [.[bslBSL]][+\-][ y ]).
 The value of
-.I x
+.Em x
 is used as an offset in the file. A byte, short or long is read at that offset
 depending on the
-.B [bslBSLm]
+.Em [bslBSLm]
 type specifier.
 The capitalized types interpret the number as a big endian
 value, whereas the small letter versions interpret the number as a little
 endian value;
 the
-.B m
+.Em m
 type interprets the number as a middle endian (PDP-11) value.
 To that number the value of
-.I y
+.Em y
 is added and the result is used as an offset in the file.
 The default type if one is not specified is long.
-.PP
+.Pp
 That way variable length structures can be examined:
-.sp
-.nf
-    # MS Windows executables are also valid MS-DOS executables
-    0           string  MZ
-    >0x18       leshort <0x40   MZ executable (MS-DOS)
-    # skip the whole block below if it is not an extended executable
-    >0x18       leshort >0x3f
-    >>(0x3c.l)  string  PE\e0\e0  PE executable (MS-Windows)
-    >>(0x3c.l)  string  LX\e0\e0  LX executable (OS/2)
-.fi
-.PP
+.Bd -literal -offset indent 
+# MS Windows executables are also valid MS-DOS executables
+0           string  MZ
+>0x18       leshort <0x40   MZ executable (MS-DOS)
+# skip the whole block below if it is not an extended executable
+>0x18       leshort >0x3f
+>>(0x3c.l)  string  PE\e0\e0  PE executable (MS-Windows)
+>>(0x3c.l)  string  LX\e0\e0  LX executable (OS/2)
+.Ed
+.Pp
 This strategy of examining has one drawback: You must make sure that
 you eventually print something, or users may get empty output (like, when
 there is neither PE\e0\e0 nor LE\e0\e0 in the above example)
-.PP
+.Pp
 If this indirect offset cannot be used as-is, there are simple calculations
 possible: appending
-.BI [+-*/%&|^]<number>
+.Em [+-*/%&|^]<number>
 inside parentheses allows one to modify
 the value read from the file before it is used as an offset:
-.sp
-.nf
-    # MS Windows executables are also valid MS-DOS executables
-    0           string  MZ
-    # sometimes, the value at 0x18 is less that 0x40 but there's still an
-    # extended executable, simply appended to the file
-    >0x18       leshort <0x40
-    >>(4.s*512) leshort 0x014c  COFF executable (MS-DOS, DJGPP)
-    >>(4.s*512) leshort !0x014c MZ executable (MS-DOS)
-.fi
-.PP
+.Bd -literal -offset indent 
+# MS Windows executables are also valid MS-DOS executables
+0           string  MZ
+# sometimes, the value at 0x18 is less that 0x40 but there's still an
+# extended executable, simply appended to the file
+>0x18       leshort <0x40
+>>(4.s*512) leshort 0x014c  COFF executable (MS-DOS, DJGPP)
+>>(4.s*512) leshort !0x014c MZ executable (MS-DOS)
+.Ed
+.Pp
 Sometimes you do not know the exact offset as this depends on the length or
 position (when indirection was used before) of preceding fields. You can
 specify an offset relative to the end of the last up-level field using
-.BI &
+.Sq &
 as a prefix to the offset:
-.sp
-.nf
-    0           string  MZ
-    >0x18       leshort >0x3f
-    >>(0x3c.l)  string  PE\e0\e0    PE executable (MS-Windows)
-    # immediately following the PE signature is the CPU type
-    >>>&0       leshort 0x14c     for Intel 80386
-    >>>&0       leshort 0x184     for DEC Alpha
-.fi
-.PP
+.Bd -literal -offset indent 
+0           string  MZ
+>0x18       leshort >0x3f
+>>(0x3c.l)  string  PE\e0\e0    PE executable (MS-Windows)
+# immediately following the PE signature is the CPU type
+>>>&0       leshort 0x14c     for Intel 80386
+>>>&0       leshort 0x184     for DEC Alpha
+.Ed
+.Pp
 Indirect and relative offsets can be combined:
-.sp
-.nf
-    0             string  MZ
-    >0x18         leshort <0x40
-    >>(4.s*512)   leshort !0x014c MZ executable (MS-DOS)
-    # if it's not COFF, go back 512 bytes and add the offset taken
-    # from byte 2/3, which is yet another way of finding the start
-    # of the extended executable
-    >>>&(2.s-514) string  LE      LE executable (MS Windows VxD driver)
-.fi
-.PP
+.Bd -literal -offset indent 
+0             string  MZ
+>0x18         leshort <0x40
+>>(4.s*512)   leshort !0x014c MZ executable (MS-DOS)
+# if it's not COFF, go back 512 bytes and add the offset taken
+# from byte 2/3, which is yet another way of finding the start
+# of the extended executable
+>>>&(2.s-514) string  LE      LE executable (MS Windows VxD driver)
+.Ed
+.Pp
 Or the other way around:
-.sp
-.nf
-    0                 string  MZ
-    >0x18             leshort >0x3f
-    >>(0x3c.l)        string  LE\e0\e0  LE executable (MS-Windows)
-    # at offset 0x80 (-4, since relative offsets start at the end
-    # of the up-level match) inside the LE header, we find the absolute
-    # offset to the code area, where we look for a specific signature
-    >>>(&0x7c.l+0x26) string  UPX     \eb, UPX compressed
-.fi
-.PP
+.Bd -literal -offset indent 
+0                 string  MZ
+>0x18             leshort >0x3f
+>>(0x3c.l)        string  LE\e0\e0  LE executable (MS-Windows)
+# at offset 0x80 (-4, since relative offsets start at the end
+# of the up-level match) inside the LE header, we find the absolute
+# offset to the code area, where we look for a specific signature
+>>>(&0x7c.l+0x26) string  UPX     \eb, UPX compressed
+.Ed
+.Pp
 Or even both!
-.sp
-.nf
-    0                string  MZ
-    >0x18            leshort >0x3f
-    >>(0x3c.l)       string  LE\e0\e0 LE executable (MS-Windows)
-    # at offset 0x58 inside the LE header, we find the relative offset
-    # to a data area where we look for a specific signature
-    >>>&(&0x54.l-3)  string  UNACE  \eb, ACE self-extracting archive
-.fi
-.PP
+.Bd -literal -offset indent 
+0                string  MZ
+>0x18            leshort >0x3f
+>>(0x3c.l)       string  LE\e0\e0 LE executable (MS-Windows)
+# at offset 0x58 inside the LE header, we find the relative offset
+# to a data area where we look for a specific signature
+>>>&(&0x54.l-3)  string  UNACE  \eb, ACE self-extracting archive
+.Ed
+.Pp
 Finally, if you have to deal with offset/length pairs in your file, even the
 second value in a parenthesized expression can be taken from the file itself,
 using another set of parentheses. Note that this additional indirect offset
 is always relative to the start of the main indirect offset.
-.sp
-.nf
-    0                 string       MZ
-    >0x18             leshort      >0x3f
-    >>(0x3c.l)        string       PE\e0\e0 PE executable (MS-Windows)
-    # search for the PE section called ".idata"...
-    >>>&0xf4          search/0x140 .idata
-    # ...and go to the end of it, calculated from start+length;
-    # these are located 14 and 10 bytes after the section name
-    >>>>(&0xe.l+(-4)) string       PK\e3\e4 \eb, ZIP self-extracting archive
-.fi
-.SH BUGS
+.Bd -literal -offset indent 
+0                 string       MZ
+>0x18             leshort      >0x3f
+>>(0x3c.l)        string       PE\e0\e0 PE executable (MS-Windows)
+# search for the PE section called ".idata"...
+>>>&0xf4          search/0x140 .idata
+# ...and go to the end of it, calculated from start+length;
+# these are located 14 and 10 bytes after the section name
+>>>>(&0xe.l+(-4)) string       PK\e3\e4 \eb, ZIP self-extracting archive
+.Ed
+.Sh BUGS
 The formats
-.IR long ,
-.IR belong ,
-.IR lelong ,
-.IR melong ,
-.IR short ,
-.IR beshort ,
-.IR leshort ,
-.IR date ,
-.IR bedate ,
-.IR medate ,
-.IR ledate ,
-.IR beldate ,
-.IR leldate ,
+.Dv long ,
+.Dv belong ,
+.Dv lelong ,
+.Dv melong ,
+.Dv short ,
+.Dv beshort ,
+.Dv leshort ,
+.Dv date ,
+.Dv bedate ,
+.Dv medate ,
+.Dv ledate ,
+.Dv beldate ,
+.Dv leldate ,
 and
-.I meldate
+.Dv meldate
 are system-dependent; perhaps they should be specified as a number
 of bytes (2B, 4B, etc),
 since the files being recognized typically come from
 a system on which the lengths are invariant.
-.SH SEE ALSO
-.BR file (__CSECTION__)
+.Sh SEE ALSO
+.Xr file __CSECTION__
 \- the command that reads this file.
 .\"
 .\" From: guy@sun.uucp (Guy Harris)
@@ -422,4 +446,4 @@ a system on which the lengths are invariant.
 .\" the changes I posted to the S5R2 version.
 .\"
 .\" Modified for Ian Darwin's version of the file command.
-.\" @(#)$Id: magic.man,v 1.33 2006/10/31 19:37:16 christos Exp $
+.\" @(#)$Id: magic.man,v 1.37 2007/01/12 17:38:27 christos Exp $

+ 0 - 805
ltcf-c.sh

@@ -1,805 +0,0 @@
-#### This script is meant to be sourced by ltconfig.
-
-# ltcf-c.sh - Create a C compiler specific configuration
-#
-# Copyright (C) 1996-2000, 2001 Free Software Foundation, Inc.
-# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-#
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='main(){return(0);}'
-
-## Linker Characteristics
-case $host_os in
-cygwin* | mingw*)
-  # FIXME: the MSVC++ port hasn't been tested in a loooong time
-  # When not using gcc, we currently assume that we are using
-  # Microsoft Visual C++.
-  if test "$with_gcc" != yes; then
-    with_gnu_ld=no
-  fi
-  ;;
-
-esac
-
-ld_shlibs=yes
-if test "$with_gnu_ld" = yes; then
-  # If archive_cmds runs LD, not CC, wlarc should be empty
-  wlarc='${wl}'
-
-  # See if GNU ld supports shared libraries.
-  case $host_os in
-  aix3* | aix4* | aix5*)
-    # On AIX, the GNU linker is very broken
-    ld_shlibs=no
-    cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support.  If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
-    ;;
-
-  amigaos*)
-    archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
-    hardcode_libdir_flag_spec='-L$libdir'
-    hardcode_minus_L=yes
-
-    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
-    # that the semantics of dynamic libraries on AmigaOS, at least up
-    # to version 4, is to share data among multiple programs linked
-    # with the same dynamic library.  Since this doesn't match the
-    # behavior of shared libraries on other platforms, we can use
-    # them.
-    ld_shlibs=no
-    ;;
-
-  beos*)
-    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
-      allow_undefined_flag=unsupported
-      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
-      # support --undefined.  This deserves some investigation.  FIXME
-      archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-    else
-      ld_shlibs=no
-    fi
-    ;;
-
-  cygwin* | mingw*)
-    # hardcode_libdir_flag_spec is actually meaningless, as there is
-    # no search path for DLLs.
-    hardcode_libdir_flag_spec='-L$libdir'
-    allow_undefined_flag=unsupported
-    always_export_symbols=yes
-
-    extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
-      sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //; p; }" -e d < $0 > $output_objdir/impgen.c~
-      test -f $output_objdir/impgen.exe || (cd $output_objdir && \
-      if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
-      else $CC -o impgen impgen.c ; fi)~
-      $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
-
-    old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
-
-    # cygwin and mingw dlls have different entry points and sets of symbols
-    # to exclude.
-    # FIXME: what about values for MSVC?
-    dll_entry=__cygwin_dll_entry@12
-    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
-    case $host_os in
-    mingw*)
-      # mingw values
-      dll_entry=_DllMainCRTStartup@12
-      dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
-      ;;
-    esac
-
-    # mingw and cygwin differ, and it's simplest to just exclude the union
-    # of the two symbol sets.
-    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
-
-    # recent cygwin and mingw systems supply a stub DllMain which the user
-    # can override, but on older systems we have to supply one (in ltdll.c)
-    if test "x$lt_cv_need_dllmain" = "xyes"; then
-      ltdll_obj='$output_objdir/$soname-ltdll.'"$objext "
-      ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $output_objdir/$soname-ltdll.c~
-	test -f $output_objdir/$soname-ltdll.$objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
-    else
-      ltdll_obj=
-      ltdll_cmds=
-    fi
-
-    # Extract the symbol export list from an `--export-all' def file,
-    # then regenerate the def file from the symbol export list, so that
-    # the compiled dll only exports the symbol export list.
-    # Be careful not to strip the DATA tag left be newer dlltools.
-    export_symbols_cmds="$ltdll_cmds"'
-      $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
-      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
-
-    # If the export-symbols file already is a .def file (1st line
-    # is EXPORTS), use it as is.
-    # If DATA tags from a recent dlltool are present, honour them!
-    archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
-        cp $export_symbols $output_objdir/$soname-def;
-      else
-        echo EXPORTS > $output_objdir/$soname-def;
-        _lt_hint=1;
-        cat $export_symbols | while read symbol; do
-         set dummy \$symbol;
-         case \[$]# in
-           2) echo "   \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
-           *) echo "     \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;;
-         esac;
-         _lt_hint=`expr 1 + \$_lt_hint`;
-        done;
-      fi~
-      '"$ltdll_cmds"'
-      $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
-      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
-      $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
-      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
-      $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
-    ;;
-
-  netbsd*)
-    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
-      archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
-      wlarc=
-    else
-      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-    fi
-    ;;
-
-  solaris* | sysv5*)
-    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
-      ld_shlibs=no
-      cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems.  Therefore, libtool
-*** is disabling shared libraries support.  We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer.  Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
-    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
-      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-    else
-      ld_shlibs=no
-    fi
-    ;;
-
-  sunos4*)
-    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-    wlarc=
-    hardcode_direct=yes
-    hardcode_shlibpath_var=no
-    ;;
-
-  *)
-    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
-      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-    else
-      ld_shlibs=no
-    fi
-    ;;
-  esac
-
-  if test "$ld_shlibs" = yes; then
-    runpath_var=LD_RUN_PATH
-    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
-    export_dynamic_flag_spec='${wl}--export-dynamic'
-    case $host_os in
-    cygwin* | mingw*)
-      # dlltool doesn't understand --whole-archive et. al.
-      whole_archive_flag_spec=
-      ;;
-    *)
-      # ancient GNU ld didn't support --whole-archive et. al.
-      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
-	whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
-      else
-	whole_archive_flag_spec=
-      fi
-      ;;
-    esac
-  fi
-else
-  # PORTME fill in a description of your system's linker (not GNU ld)
-  case $host_os in
-  aix3*)
-    allow_undefined_flag=unsupported
-    always_export_symbols=yes
-    archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
-    # Note: this linker hardcodes the directories in LIBPATH if there
-    # are no directories specified by -L.
-    hardcode_minus_L=yes
-    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
-      # Neither direct hardcoding nor static linking is supported with a
-      # broken collect2.
-      hardcode_direct=unsupported
-    fi
-    ;;
-
-  aix4* | aix5*)
-    hardcode_direct=yes
-    hardcode_libdir_separator=':'
-    link_all_deplibs=yes
-    # When large executables or shared objects are built, AIX ld can
-    # have problems creating the table of contents.  If linking a library
-    # or program results in "error TOC overflow" add -mminimal-toc to
-    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
-    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-    if test "$with_gcc" = yes; then
-      case $host_os in aix4.[012]|aix4.[012].*)
-      # We only want to do this on AIX 4.2 and lower, the check
-      # below for broken collect2 doesn't work under 4.3+
-        collect2name=`${CC} -print-prog-name=collect2`
-        if test -f "$collect2name" && \
-	   strings "$collect2name" | grep resolve_lib_name >/dev/null
-        then
-	  # We have reworked collect2
-	  hardcode_direct=yes
-        else
-	  # We have old collect2
-	  hardcode_direct=unsupported
-	  # It fails to find uninstalled libraries when the uninstalled
-	  # path is not listed in the libpath.  Setting hardcode_minus_L
-	  # to unsupported forces relinking
-	  hardcode_minus_L=yes
-	  hardcode_libdir_flag_spec='-L$libdir'
-	  hardcode_libdir_separator=
-        fi
-      esac
-      shared_flag='-shared'
-    else
-      # not using gcc
-      if test "$host_cpu" = ia64; then
-        shared_flag='${wl}-G'
-      else
-        shared_flag='${wl}-bM:SRE'
-      fi
-    fi
-
-    if test "$host_cpu" = ia64; then
-      # On IA64, the linker does run time linking by default, so we don't
-      # have to do anything special.
-      aix_use_runtimelinking=no
-      exp_sym_flag='-Bexport'
-      no_entry_flag=""
-    else
-      # Test if we are trying to use run time linking, or normal AIX style linking.
-      # If -brtl is somewhere in LDFLAGS, we need to do run time linking.
-      aix_use_runtimelinking=no
-      for ld_flag in $LDFLAGS; do
-        if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl" ); then
-          aix_use_runtimelinking=yes
-          break
-        fi
-      done
-      exp_sym_flag='-bexport'
-      no_entry_flag='-bnoentry'
-    fi
-    # -bexpall does not export symbols beginning with underscore (_)
-    always_export_symbols=yes
-    if test "$aix_use_runtimelinking" = yes; then
-      # Warning - without using the other run time loading flags (-brtl), -berok will
-      #           link without error, but may produce a broken library.
-      allow_undefined_flag=' ${wl}-berok'
-      hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
-      archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
-    else
-      if test "$host_cpu" = ia64; then
-        hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
-        allow_undefined_flag="-z nodefs"
-        archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
-      else
-        allow_undefined_flag=' ${wl}-berok'
-        # -bexpall does not export symbols beginning with underscore (_)
-        always_export_symbols=yes
-        # Exported symbols can be pulled into shared objects from archives
-        whole_archive_flag_spec=' '
-        build_libtool_need_lc=yes
-        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
-        # This is similar to how AIX traditionally builds it's shared libraries.
-        archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
-      fi
-    fi
-    ;;
-
-  amigaos*)
-    archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
-    hardcode_libdir_flag_spec='-L$libdir'
-    hardcode_minus_L=yes
-    # see comment about different semantics on the GNU ld section
-    ld_shlibs=no
-    ;;
-
-  cygwin* | mingw*)
-    # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++.
-    # hardcode_libdir_flag_spec is actually meaningless, as there is
-    # no search path for DLLs.
-    hardcode_libdir_flag_spec=' '
-    allow_undefined_flag=unsupported
-    # Tell ltmain to make .lib files, not .a files.
-    libext=lib
-    # FIXME: Setting linknames here is a bad hack.
-    archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
-    # The linker will automatically build a .lib file if we build a DLL.
-    old_archive_from_new_cmds='true'
-    # FIXME: Should let the user specify the lib program.
-    old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
-    fix_srcfile_path='`cygpath -w "$srcfile"`'
-    ;;
-
-  darwin* | rhapsody*)
-    case "$host_os" in
-    rhapsody* | darwin1.[012])
-      allow_undefined_flag='-undefined suppress'
-      ;;
-    *) # Darwin 1.3 on
-      allow_undefined_flag='-flat_namespace -undefined suppress'
-      ;;
-    esac
-    archive_cmds='$CC $(if test .$module = .yes; then echo -bundle; else echo -dynamiclib; fi) $allow_undefined_flag -o $lib $libobjs $deplibs $linkopts -install_name $rpath/$soname $verstring'
-    # We need to add '_' to the symbols in $export_symbols first
-    #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols $lib'
-    hardcode_direct=yes
-    hardcode_shlibpath_var=no
-    whole_archive_flag_spec='-all_load $convenience'
-    ;;
-
-  freebsd1*)
-    ld_shlibs=no
-    ;;
-
-  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
-  # support.  Future versions do this automatically, but an explicit c++rt0.o
-  # does not break anything, and helps significantly (at the cost of a little
-  # extra space).
-  freebsd2.2*)
-    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
-    hardcode_libdir_flag_spec='-R$libdir'
-    hardcode_direct=yes
-    hardcode_shlibpath_var=no
-    ;;
-
-  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
-  freebsd2*)
-    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-    hardcode_direct=yes
-    hardcode_minus_L=yes
-    hardcode_shlibpath_var=no
-    ;;
-
-  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
-  freebsd*)
-    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
-    hardcode_libdir_flag_spec='-R$libdir'
-    hardcode_direct=yes
-    hardcode_shlibpath_var=no
-    ;;
-
-  hpux9* | hpux10* | hpux11*)
-    case $host_os in
-    hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
-    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
-    esac
-    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
-    hardcode_libdir_separator=:
-    hardcode_direct=yes
-    hardcode_minus_L=yes # Not in the search PATH, but as the default
-			 # location of the library.
-    export_dynamic_flag_spec='${wl}-E'
-    ;;
-
-  irix5* | irix6*)
-    if test "$with_gcc" = yes; then
-      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
-    else
-      archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
-    fi
-    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-    hardcode_libdir_separator=:
-    link_all_deplibs=yes
-    ;;
-
-  netbsd*)
-    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
-      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
-    else
-      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
-    fi
-    hardcode_libdir_flag_spec='-R$libdir'
-    hardcode_direct=yes
-    hardcode_shlibpath_var=no
-    ;;
-
-  newsos6)
-    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
-    hardcode_direct=yes
-    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-    hardcode_libdir_separator=:
-    hardcode_shlibpath_var=no
-    ;;
-
-  openbsd*)
-    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-    hardcode_libdir_flag_spec='-R$libdir'
-    hardcode_direct=yes
-    hardcode_shlibpath_var=no
-    ;;
-
-  os2*)
-    hardcode_libdir_flag_spec='-L$libdir'
-    hardcode_minus_L=yes
-    allow_undefined_flag=unsupported
-    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
-    old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
-    ;;
-
-  osf3*)
-    if test "$with_gcc" = yes; then
-      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
-      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
-    else
-      allow_undefined_flag=' -expect_unresolved \*'
-      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
-    fi
-    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-    hardcode_libdir_separator=:
-    ;;
-
-  osf4* | osf5*)	# as osf3* with the addition of -msym flag
-    if test "$with_gcc" = yes; then
-      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
-      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
-      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-    else
-      allow_undefined_flag=' -expect_unresolved \*'
-      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
-      archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
-      $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
-
-      # cc supports -rpath directly
-      hardcode_libdir_flag_spec='-rpath $libdir'
-    fi
-    hardcode_libdir_separator=:
-    ;;
-
-  sco3.2v5*)
-    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-    hardcode_shlibpath_var=no
-    runpath_var=LD_RUN_PATH
-    hardcode_runpath_var=yes
-    ;;
-
-  solaris*)
-    no_undefined_flag=' -z defs'
-    # $CC -shared without GNU ld will not create a library from C++
-    # object files and a static libstdc++, better avoid it by now
-    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
-    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
-    hardcode_libdir_flag_spec='-R$libdir'
-    hardcode_shlibpath_var=no
-    case $host_os in
-    solaris2.[0-5] | solaris2.[0-5].*) ;;
-    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
-      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
-    esac
-    link_all_deplibs=yes
-    ;;
-
-  sunos4*)
-    archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
-    hardcode_libdir_flag_spec='-L$libdir'
-    hardcode_direct=yes
-    hardcode_minus_L=yes
-    hardcode_shlibpath_var=no
-    ;;
-
-  sysv4)
-    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-    runpath_var='LD_RUN_PATH'
-    hardcode_shlibpath_var=no
-    hardcode_direct=no #Motorola manual says yes, but my tests say they lie
-    ;;
-
-  sysv4.3*)
-    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-    hardcode_shlibpath_var=no
-    export_dynamic_flag_spec='-Bexport'
-    ;;
-
-  sysv5*)
-    no_undefined_flag=' -z text'
-    # $CC -shared without GNU ld will not create a library from C++
-    # object files and a static libstdc++, better avoid it by now
-    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
-    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
-    hardcode_libdir_flag_spec=
-    hardcode_shlibpath_var=no
-    runpath_var='LD_RUN_PATH'
-    ;;
-
-  uts4*)
-    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-    hardcode_libdir_flag_spec='-L$libdir'
-    hardcode_shlibpath_var=no
-    ;;
-
-  dgux*)
-    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-    hardcode_libdir_flag_spec='-L$libdir'
-    hardcode_shlibpath_var=no
-    ;;
-
-  sysv4*MP*)
-    if test -d /usr/nec; then
-      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      hardcode_shlibpath_var=no
-      runpath_var=LD_RUN_PATH
-      hardcode_runpath_var=yes
-      ld_shlibs=yes
-    fi
-    ;;
-
-  sysv4.2uw2*)
-    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
-    hardcode_direct=yes
-    hardcode_minus_L=no
-    hardcode_shlibpath_var=no
-    hardcode_runpath_var=yes
-    runpath_var=LD_RUN_PATH
-    ;;
-
-  sysv5uw7* | unixware7*)
-    no_undefined_flag='${wl}-z ${wl}text'
-    if test "$GCC" = yes; then
-      archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
-    else
-      archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
-    fi
-    runpath_var='LD_RUN_PATH'
-    hardcode_shlibpath_var=no
-    ;;
-
-  *)
-    ld_shlibs=no
-    ;;
-  esac
-fi
-
-## Compiler Characteristics: PIC flags, static flags, etc
-if test "X${ac_cv_prog_cc_pic+set}" = Xset; then
-  :
-else
-  ac_cv_prog_cc_pic=
-  ac_cv_prog_cc_shlib=
-  ac_cv_prog_cc_wl=
-  ac_cv_prog_cc_static=
-  ac_cv_prog_cc_no_builtin=
-  ac_cv_prog_cc_can_build_shared=$can_build_shared
-
-  if test "$with_gcc" = yes; then
-    ac_cv_prog_cc_wl='-Wl,'
-    ac_cv_prog_cc_static='-static'
-
-    case $host_os in
-    aix*)
-      # All AIX code is PIC.
-      if test "$host_cpu" = ia64; then
-        # AIX 5 now supports IA64 processor
-        lt_cv_prog_cc_static='-Bstatic'
-      else
-        lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
-      fi
-      ;;
-    amigaos*)
-      # FIXME: we need at least 68020 code to build shared libraries, but
-      # adding the `-m68020' flag to GCC prevents building anything better,
-      # like `-m68040'.
-      ac_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
-      ;;
-    beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
-      # PIC is the default for these OSes.
-      ;;
-    cygwin* | mingw* | os2*)
-      # This hack is so that the source file can tell whether it is being
-      # built for inclusion in a dll (and should export symbols for example).
-      ac_cv_prog_cc_pic='-DDLL_EXPORT'
-      ;;
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      ac_cv_prog_cc_pic='-fno-common'
-      ;;
-    *djgpp*)
-      # DJGPP does not support shared libraries at all
-      ac_cv_prog_cc_pic=
-      ;;
-    sysv4*MP*)
-      if test -d /usr/nec; then
-	 ac_cv_prog_cc_pic=-Kconform_pic
-      fi
-      ;;
-    *)
-      ac_cv_prog_cc_pic='-fPIC'
-      ;;
-    esac
-  else
-    # PORTME Check for PIC flags for the system compiler.
-    case $host_os in
-    aix*)
-     # All AIX code is PIC.
-      ac_cv_prog_cc_static="$ac_cv_prog_cc_static ${ac_cv_prog_cc_wl}-lC"
-      ;;
-
-    hpux9* | hpux10* | hpux11*)
-      # Is there a better ac_cv_prog_cc_static that works with the bundled CC?
-      ac_cv_prog_cc_wl='-Wl,'
-      ac_cv_prog_cc_static="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
-      ac_cv_prog_cc_pic='+Z'
-      ;;
-
-    irix5* | irix6*)
-      ac_cv_prog_cc_wl='-Wl,'
-      ac_cv_prog_cc_static='-non_shared'
-      # PIC (with -KPIC) is the default.
-      ;;
-
-    cygwin* | mingw* | os2*)
-      # This hack is so that the source file can tell whether it is being
-      # built for inclusion in a dll (and should export symbols for example).
-      ac_cv_prog_cc_pic='-DDLL_EXPORT'
-      ;;
-
-    newsos6)
-      ac_cv_prog_cc_pic='-KPIC'
-      ac_cv_prog_cc_static='-Bstatic'
-      ;;
-
-    osf3* | osf4* | osf5*)
-      # All OSF/1 code is PIC.
-      ac_cv_prog_cc_wl='-Wl,'
-      ac_cv_prog_cc_static='-non_shared'
-      ;;
-
-    sco3.2v5*)
-      ac_cv_prog_cc_pic='-Kpic'
-      ac_cv_prog_cc_static='-dn'
-      ac_cv_prog_cc_shlib='-belf'
-      ;;
-
-    solaris*)
-      ac_cv_prog_cc_pic='-KPIC'
-      ac_cv_prog_cc_static='-Bstatic'
-      ac_cv_prog_cc_wl='-Wl,'
-      ;;
-
-    sunos4*)
-      ac_cv_prog_cc_pic='-PIC'
-      ac_cv_prog_cc_static='-Bstatic'
-      ac_cv_prog_cc_wl='-Qoption ld '
-      ;;
-
-    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
-      ac_cv_prog_cc_pic='-KPIC'
-      ac_cv_prog_cc_static='-Bstatic'
-      ac_cv_prog_cc_wl='-Wl,'
-      ;;
-
-    uts4*)
-      ac_cv_prog_cc_pic='-pic'
-      ac_cv_prog_cc_static='-Bstatic'
-      ;;
-
-    sysv4*MP*)
-      if test -d /usr/nec ;then
-	ac_cv_prog_cc_pic='-Kconform_pic'
-	ac_cv_prog_cc_static='-Bstatic'
-      fi
-      ;;
-
-    *)
-      ac_cv_prog_cc_can_build_shared=no
-      ;;
-    esac
-  fi
-  case "$host_os" in
-      # Platforms which do not suport PIC and -DPIC is meaningless
-      # on them:
-      *djgpp*)
-        ac_cv_prog_cc_pic=
-        ;;
-      *)
-        ac_cv_prog_cc_pic="$ac_cv_prog_cc_pic -DPIC"
-        ;;
-  esac
-fi
-
-need_lc=yes
-if test "$enable_shared" = yes && test "$with_gcc" = yes; then
-  case $archive_cmds in
-  *'~'*)
-    # FIXME: we may have to deal with multi-command sequences.
-    ;;
-  '$CC '*)
-    # Test whether the compiler implicitly links with -lc since on some
-    # systems, -lgcc has to come before -lc. If gcc already passes -lc
-    # to ld, don't add -lc before -lgcc.
-    echo $ac_n "checking whether -lc should be explicitly linked in... $ac_c" 1>&6
-    if eval "test \"`echo '$''{'ac_cv_archive_cmds_needs_lc'+set}'`\" = set"; then
-      echo $ac_n "(cached) $ac_c" 1>&6
-      need_lc=$ac_cv_archive_cmds_needs_lc
-    else
-      $rm conftest*
-      echo "static int dummy;" > conftest.$ac_ext
-      if { (eval echo ltcf-c.sh:need_lc: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
-	# Append any warnings to the config.log.
-	cat conftest.err 1>&5
-	soname=conftest
-	lib=conftest
-	libobjs=conftest.$ac_objext
-	deplibs=
-	wl=$ac_cv_prog_cc_wl
-	compiler_flags=-v
-	linker_flags=-v
-	verstring=
-	output_objdir=.
-	libname=conftest
-	save_allow_undefined_flag=$allow_undefined_flag
-	allow_undefined_flag=
-	if { (eval echo ltcf-c.sh:need_lc: \"$archive_cmds\") 1>&5; (eval $archive_cmds) 2>&1 | grep " -lc " 1>&5 ; }; then
-	  need_lc=no
-	fi
-	allow_undefined_flag=$save_allow_undefined_flag
-      else
-	cat conftest.err 1>&5
-      fi
-    fi
-    $rm conftest*
-    echo "$ac_t$need_lc" 1>&6
-    ;;
-  esac
-fi
-ac_cv_archive_cmds_needs_lc=$need_lc

+ 1 - 1
magic/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.

+ 3 - 3
magic/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

+ 1 - 1
magic/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,

+ 11 - 4
magic/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,10 @@
 >>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

+ 2 - 2
magic/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)

+ 1 - 1
magic/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

+ 3 - 0
magic/Magdir/console

@@ -165,3 +165,6 @@
 # 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

+ 0 - 4
magic/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

+ 2 - 1
magic/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

+ 2 - 1
magic/Magdir/elf

@@ -167,8 +167,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		PowerPC 64-bit or 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,

+ 290 - 79
magic/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,
@@ -986,3 +1192,8 @@
 #>>&(&0.b+8)  byte    0x42       OpenVMS backup saveset data
 #>>>40        lelong  x          (block size %d
 #>>>49        string  >\0        original name '%s')
+
+# Compaq/HP RILOE floppy image
+# From: Dirk Jagdmann <doj@cubic.org>
+0	string	CPQRFBLO	Compaq/HP RILOE floppy image
+

+ 0 - 3
magic/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
 

+ 1 - 1
magic/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

+ 1 - 1
magic/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

+ 2 - 2
magic/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

+ 2 - 2
magic/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)

+ 15 - 12
magic/Magdir/msdos

@@ -14,7 +14,7 @@
 
 # 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 =^\\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
@@ -262,8 +262,9 @@
 # Uncommenting only the first two lines will cover about 2/3 of COM files,
 # but it isn't feasible to match all COM files since there must be at least
 # two dozen different one-byte "magics".
-0	byte		0xe9		DOS executable (COM)
->0x1FE	leshort		0xAA55		\b, boot code
+# Disabled one-byte magic (MPi)
+#0	byte		0xe9		DOS executable (COM)
+#>0x1FE	leshort		0xAA55		\b, boot code
 >6	string		SFX\ of\ LHarc	(%s)
 0	belong	0xffffffff		DOS executable (device driver)
 #CMD640X2.SYS
@@ -286,15 +287,16 @@
 >>77	string	>\x40			
 >>>77	string	<\x5B			
 >>>>77	string	x			\b, name: %.8s
-0	byte		0x8c		DOS executable (COM)
+# Disabled one-byte magic (MPi)
+#0	byte		0x8c		DOS executable (COM)
 # 0xeb conflicts with "sequent" magic
-0	byte		0xeb		DOS executable (COM)
->0x1FE	leshort		0xAA55		\b, boot code
->85	string		UPX		\b, UPX compressed
->4	string		\ $ARX		\b, ARX self-extracting archive
->4	string		\ $LHarc	\b, LHarc self-extracting archive
->0x20e	string		SFX\ by\ LARC	\b, LARC self-extracting archive
-0	byte		0xb8		COM executable
+#0	byte		0xeb		DOS executable (COM)
+#>0x1FE	leshort		0xAA55		\b, boot code
+#>85	string		UPX		\b, UPX compressed
+#>4	string		\ $ARX		\b, ARX self-extracting archive
+#>4	string		\ $LHarc	\b, LHarc self-extracting archive
+#>0x20e	string		SFX\ by\ LARC	\b, LARC self-extracting archive
+#0	byte		0xb8		COM executable
 # modified by Joerg Jenderek
 >1	lelong          !0x21cd4cff	for DOS
 # http://syslinux.zytor.com/comboot.php
@@ -618,5 +620,6 @@
 0	lelong	0x02468ace			Bochs Sparse disk image
 
 # from http://filext.com by Derek M Jones <derek@knosof.co.uk>
-0	string	\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x03\x00\xFE\xFF	Microsoft Installer
+# False positive with PPT
+#0	string	\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x03\x00\xFE\xFF	Microsoft Installer
 0	string	\320\317\021\340\241\261\032\341	Microsoft Office Document

+ 1 - 1
magic/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

+ 14 - 6
magic/Magdir/perl

@@ -9,14 +9,22 @@
 0	string		eval\ "exec\ /bin/perl		perl script text
 0	string/b	#!\ /usr/bin/perl		perl script text executable
 0	string		eval\ "exec\ /usr/bin/perl	perl script text
-0	string/b	#!\ /usr/local/bin/perl		perl script text
-0	string		eval\ "exec\ /usr/local/bin/perl	perl script text executable
+0	string/b	#!\ /usr/local/bin/perl		perl script text executable
+0	string		eval\ "exec\ /usr/local/bin/perl	perl script text
 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>

+ 2 - 1
magic/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)

+ 15 - 4
magic/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

+ 14 - 14
magic/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
 

+ 1 - 1
magic/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
 

+ 6 - 0
magic/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'
+

+ 1 - 1
magic/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

+ 1 - 1
magic/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

+ 20 - 9
magic/magic.mime

@@ -156,9 +156,7 @@
 
 # Creative Labs AUDIO stuff
 #					Standard MIDI data
-0	string	MThd			audio/unknown
-#>9 	byte	>0			(format %d)
-#>11	byte	>1			using %d channels
+0	string	MThd			audio/midi
 #					Creative Music (CMF) data
 0	string	CTMF			audio/unknown
 #					SoundBlaster instrument data
@@ -193,7 +191,12 @@
 0       beshort         0x4De1          audio/MP4A-LATM
 
 # MPEG Layer 3 sound files
-0       beshort&0xfffe  =0xfffa         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
@@ -296,7 +299,7 @@
 #0	string		\037\235	application/x-compress
 
 # gzip (GNU zip, not to be confused with [Info-ZIP/PKWARE] zip archiver)
-#0       string          \037\213        application/x-gzip
+0       string          \037\213        application/x-gzip
 
 0		string			PK\003\004		application/x-zip
 
@@ -404,8 +407,6 @@
 0	string		\<!--	text/html
 0	string/c	\<h1	text/html
 
-0	string		\<?xml			text/xml
-
 
 #------------------------------------------------------------------------------
 # images:  file(1) magic for image formats (see also "c-lang" for XPM bitmaps)
@@ -586,6 +587,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
 #
@@ -673,9 +682,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
@@ -866,6 +875,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)
 #

+ 1 - 1
magic/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

+ 427 - 117
src/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.104 2007/01/19 19:54:39 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,6 +320,8 @@ 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)
@@ -316,6 +387,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 +475,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 +563,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 +618,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 +664,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 +672,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 +823,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 +840,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 +867,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 +893,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 +967,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 +983,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 +995,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 +1081,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 +1119,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 +1140,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 +1337,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 +1348,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 +1376,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 +1391,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 +1459,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 +1478,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 +1525,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 +1551,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 +1576,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 +1840,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);
+	}
 }

+ 1 - 1
src/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__

+ 15 - 10
src/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.49 2007/01/25 21:05:46 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) &&
+	    (*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]];

+ 26 - 19
src/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.50 2007/03/01 22:14:54 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 rv;
 
 			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) {
+			rv = select(fd + 1, &check, NULL, NULL, &tout);
+			if (rv == -1) {
 				if (errno == EINTR || errno == EAGAIN)
 					continue;
+			} else if (rv == 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));

+ 35 - 5
src/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.107 2007/01/25 21:05:46 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,7 +122,7 @@ 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;
@@ -138,6 +138,7 @@ main(int argc, char *argv[])
 		{"brief", 0, 0, 'b'},
 		{"checking-printout", 0, 0, 'c'},
 		{"debug", 0, 0, 'd'},
+		{"exclude", 0, 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();
@@ -331,7 +358,7 @@ main(int argc, char *argv[])
 
 private void
 /*ARGSUSED*/
-load(const char *m, int flags)
+load(const char *m __unused, int flags)
 {
 	if (magic)
 		return;
@@ -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"

+ 133 - 113
src/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.89 2007/03/01 22:14:54 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,28 @@
 #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 __unused
+#if __GNUC_PREREQ__(2, 7)
+#define	__unused	__attribute__((__unused__))
+#else
+#define	__unused	/* delete */
+#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 +99,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 +111,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 +154,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 +190,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 +211,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 +262,79 @@ 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);
+#ifdef ENABLE_CONDITIONALS
+protected int file_check_mem(struct magic_set *, unsigned int);
+#endif
 
 #ifndef COMPILE_ONLY
 extern const char *file_names[];

+ 1 - 1
src/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

+ 99 - 33
src/funcs.c

@@ -26,6 +26,7 @@
  */
 #include "file.h"
 #include "magic.h"
+#include <assert.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
@@ -38,7 +39,7 @@
 #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.28 2007/03/01 22:14:54 christos Exp $")
 #endif	/* lint */
 
 #ifndef HAVE_VSNPRINTF
@@ -52,28 +53,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 +86,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 +109,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 +152,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 +194,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
@@ -172,8 +235,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 +244,17 @@ 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 */
+	psize = len * 4 + 1;
+	assert(psize > len);
+	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)
@@ -242,8 +308,8 @@ file_getbuffer(struct magic_set *ms)
 }
 
 /*
- * 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

+ 1 - 1
src/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') )

+ 8 - 33
src/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.40 2007/03/01 22:14:55 christos Exp $")
 #endif	/* lint */
 
 #ifdef __EMX__
@@ -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,11 +102,10 @@ 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;
@@ -162,7 +161,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 +304,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 +333,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 +353,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);

+ 20 - 11
src/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" {

+ 1 - 1
src/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.26 2007/01/12 17:38:28 christos Exp $
  */
 
 /*

+ 8 - 2
src/patchlevel.h

@@ -1,11 +1,17 @@
 #define	FILE_VERSION_MAJOR	4
-#define	patchlevel		19
+#define	patchlevel		20
 
 /*
  * 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.64 2007/03/01 22:14:55 christos Exp $
  *
  * $Log: patchlevel.h,v $
+ * 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
  *

+ 33 - 19
src/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.58 2007/01/16 14:58:48 ljt Exp $")
 #endif  /* lint */
 
 #define SZOF(a)	(sizeof(a) / sizeof(a[0]))
@@ -64,8 +64,8 @@ file_mdump(struct magic *m)
 		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] : '?',
+			       ((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 *

+ 4 - 4
src/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;
 		}
@@ -866,7 +866,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;

File diff suppressed because it is too large
+ 453 - 305
src/softmagic.c


+ 1 - 71
src/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

+ 4 - 4
src/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);