Browse Source

Import upstream version 4.20

Christos Zoulas 17 years ago
parent
commit
6a25f8b348

+ 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>
 2006-12-11 16:49 Christos Zoulas <christos@zoulas.com>
 
 
 	* fix byteswapping issue
 	* 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.
 Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
 Software written by Ian F. Darwin and others;
 Software written by Ian F. Darwin and others;
 maintained 1994- Christos Zoulas.
 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:
 Maintenance notes:
 
 
 I am continuing to maintain the file command. I welcome your help,
 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:
 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.
 - Do not distribute changed versions.
 
 
 People trying to be helpful occasionally put up their hacked 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 \
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
 	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
 	$(top_srcdir)/configure ChangeLog config.guess config.sub \
 	$(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 = .
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \

+ 1 - 1
README

@@ -1,5 +1,5 @@
 ** README for file(1) Command **
 ** 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)
 This is Release 4.x of Ian Darwin's (copyright but distributable)
 file(1) command. This version is the standard "file" command for Linux,
 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. */
 /* Define to 1 if you have the <string.h> header file. */
 #undef HAVE_STRING_H
 #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. */
 /* Define to 1 if you have the `strtoul' function. */
 #undef HAVE_STRTOUL
 #undef HAVE_STRTOUL
 
 
@@ -82,6 +85,9 @@
 /* Define to 1 if you have the <sys/stat.h> header file. */
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #undef HAVE_SYS_STAT_H
 #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. */
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 #undef HAVE_SYS_TYPES_H
 
 

+ 5 - 3
configure

@@ -1808,7 +1808,7 @@ fi
 
 
 # Define the identity of the package.
 # Define the identity of the package.
  PACKAGE=file
  PACKAGE=file
- VERSION=4.19
+ VERSION=4.20
 
 
 
 
 cat >>confdefs.h <<_ACEOF
 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
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
 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
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
 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.
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT
 AC_INIT
 AC_CONFIG_SRCDIR([src/file.c])
 AC_CONFIG_SRCDIR([src/file.c])
-AM_INIT_AUTOMAKE(file, 4.19)
+AM_INIT_AUTOMAKE(file, 4.20)
 AM_CONFIG_HEADER([config.h])
 AM_CONFIG_HEADER([config.h])
 AM_MAINTAINER_MODE
 AM_MAINTAINER_MODE
 
 
@@ -81,7 +81,7 @@ AC_HEADER_SYS_WAIT
 AC_HEADER_STDINT
 AC_HEADER_STDINT
 AC_CHECK_HEADERS(fcntl.h locale.h stdint.h inttypes.h unistd.h getopt.h)
 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(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.
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 AC_C_CONST
@@ -119,7 +119,7 @@ AC_CHECK_SIZEOF_STDC_HEADERS(uint32_t, 0)
 AC_CHECK_SIZEOF_STDC_HEADERS(uint64_t, 0)
 AC_CHECK_SIZEOF_STDC_HEADERS(uint64_t, 0)
 
 
 dnl Checks for functions
 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
 dnl Checks for libraries
 AC_CHECK_LIB(z,gzopen)
 AC_CHECK_LIB(z,gzopen)

+ 315 - 255
doc/file.man

@@ -1,78 +1,73 @@
-.TH FILE __CSECTION__ "Copyright 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
 This manual page documents version __VERSION__ of the
-.B file
+.Nm
 command.
 command.
-.PP
-.B File
+.Pp
+.Nm
 tests each argument in an attempt to classify it.
 tests each argument in an attempt to classify it.
 There are three sets of tests, performed in this order:
 There are three sets of tests, performed in this order:
 filesystem tests, magic number tests, and language tests.
 filesystem tests, magic number tests, and language tests.
 The
 The
-.I first
+.Em first
 test that succeeds causes the file type to be printed.
 test that succeeds causes the file type to be printed.
-.PP
+.Pp
 The type printed will usually contain one of the words
 The type printed will usually contain one of the words
-.B text
+.Em text
 (the file contains only
 (the file contains only
 printing characters and a few common control
 printing characters and a few common control
 characters and is probably safe to read on an
 characters and is probably safe to read on an
-.SM ASCII
+.Dv ASCII
 terminal),
 terminal),
-.B executable
+.Em executable
 (the file contains the result of compiling a program
 (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
 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)
 Exceptions are well-known file formats (core files, tar archives)
 that are known to contain binary data.
 that are known to contain binary data.
 When modifying the file
 When modifying the file
-.I __MAGIC__
-or the program itself, 
-.B "preserve these keywords" .
+.Pa __MAGIC__
+or the program itself, make sure to
+.Em "preserve these keywords" .
 People depend on knowing that all the readable files in a directory
 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
 Note that the file
-.I __MAGIC__
+.Pa __MAGIC__
 is built mechanically from a large number of small files in
 is built mechanically from a large number of small files in
 the subdirectory
 the subdirectory
-.I Magdir
+.Pa Magdir
 in the source distribution of this program.
 in the source distribution of this program.
-.PP
+.Pp
 The filesystem tests are based on examining the return from a
 The filesystem tests are based on examining the return from a
-.BR stat (2)
+.Xr stat 2
 system call.
 system call.
 The program checks to see if the file is empty,
 The program checks to see if the file is empty,
 or if it's some sort of special file.
 or if it's some sort of special file.
@@ -81,36 +76,42 @@ Any known file types appropriate to the system you are running on
 implement them)
 implement them)
 are intuited if they are defined in
 are intuited if they are defined in
 the system header file
 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
 The magic number tests are used to check for files with data in
 particular fixed formats.
 particular fixed formats.
 The canonical example of this is a binary executable (compiled program)
 The canonical example of this is a binary executable (compiled program)
-.I a.out
+.Dv a.out
 file, whose format is defined in 
 file, whose format is defined in 
-.I a.out.h
+.In elf.h ,
+.In a.out.h
 and possibly
 and possibly
-.I exec.h
+.In exec.h
 in the standard include directory.
 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.
 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
 Any file with some invariant identifier at a small fixed
 offset into the file can usually be described in this way.
 offset into the file can usually be described in this way.
 The information identifying these files is read from the compiled
 The information identifying these files is read from the compiled
 magic file
 magic file
-.I __MAGIC__.mgc ,
+.Pa __MAGIC__.mgc ,
 or 
 or 
-.I __MAGIC__
+.Pa __MAGIC__
 if the compile file does not exist. In addition
 if the compile file does not exist. In addition
-.B file
+.Nm
 will look in
 will look in
-.I $HOME/.magic.mgc ,
+.Pa $HOME/.magic.mgc ,
 or
 or
-.I $HOME/.magic
+.Pa $HOME/.magic
 for magic entries.
 for magic entries.
-.PP
+.Pp
 If a file does not match any of the entries in the magic file,
 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.
 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
 ASCII, ISO-8859-x, non-ISO 8-bit extended-ASCII character sets
@@ -121,208 +122,241 @@ ranges and sequences of bytes that constitute printable text
 in each set.
 in each set.
 If a file passes any of these tests, its character set is reported.
 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
 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
 they contain text, it is text that will require translation
 before it can be read.
 before it can be read.
 In addition,
 In addition,
-.B file
+.Nm
 will attempt to determine other characteristics of text-type files.
 will attempt to determine other characteristics of text-type files.
 If the lines of a file are terminated by CR, CRLF, or NEL, instead
 If the lines of a file are terminated by CR, CRLF, or NEL, instead
 of the Unix-standard LF, this will be reported.
 of the Unix-standard LF, this will be reported.
 Files that contain embedded escape sequences or overstriking
 Files that contain embedded escape sequences or overstriking
 will also be identified.
 will also be identified.
-.PP
+.Pp
 Once
 Once
-.B file
+.Nm
 has determined the character set used in a text-type file,
 has determined the character set used in a text-type file,
 it will
 it will
 attempt to determine in what language the file is written.
 attempt to determine in what language the file is written.
 The language tests look for particular strings (cf
 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.
 that can appear anywhere in the first few blocks of a file.
 For example, the keyword
 For example, the keyword
-.B .br
+.Em .br
 indicates that the file is most likely a
 indicates that the file is most likely a
-.BR troff (1)
+.Xr troff 1
 input file, just as the keyword 
 input file, just as the keyword 
-.B struct
+.Em struct
 indicates a C program.
 indicates a C program.
 These tests are less reliable than the previous
 These tests are less reliable than the previous
 two groups, so they are performed last.
 two groups, so they are performed last.
 The language test routines also test for some miscellany
 The language test routines also test for some miscellany
 (such as 
 (such as 
-.BR tar (1)
+.Xr tar 1
 archives).
 archives).
-.PP
+.Pp
 Any file that cannot be identified as having been written
 Any file that cannot be identified as having been written
 in any of the character sets listed above is simply said to be ``data''.
 in any of the character sets listed above is simply said to be ``data''.
-.SH OPTIONS
-.TP 8
-.B "\-b, \-\-brief"
+.Sh OPTIONS
+.Bl -tag -width indent
+.It Fl b , -brief
 Do not prepend filenames to output lines (brief mode).
 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.
 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 
 Read the names of the files to be examined from 
-.I namefile
+.Ar namefile
 (one per line) 
 (one per line) 
 before the argument list.
 before the argument list.
 Either 
 Either 
-.I namefile
+.Ar namefile
 or at least one filename argument must be present;
 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
 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
 option causes symlinks not to be followed
 (on systems that support symbolic links). This is the default if the
 (on systems that support symbolic links). This is the default if the
 environment variable
 environment variable
-.I POSIXLY_CORRECT
+.Dv POSIXLY_CORRECT
 is not defined.
 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
 Causes the file command to output mime type strings rather than the more
 traditional human readable ones. Thus it may say
 traditional human readable ones. Thus it may say
-``text/plain; charset=us-ascii''
+.Dq text/plain; charset=us-ascii
 rather
 rather
-than ``ASCII text''.
+than
+.Dq ASCII text .
 In order for this option to work, file changes the way
 In order for this option to work, file changes the way
 it handles files recognized by the command itself (such as many of the
 it handles files recognized by the command itself (such as many of the
 text file types, directories etc), and makes use of an alternative
 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.
 Don't stop at the first match, keep going.
-.TP 8
-.B "\-L, \-\-dereference"
+.It Fl L , -dereference
 option causes symlinks to be followed, as the like-named option in
 option causes symlinks to be followed, as the like-named option in
-.BR ls (1)
+.Xr ls 1
 (on systems that support symbolic links).
 (on systems that support symbolic links).
 This is the default if the environment variable
 This is the default if the environment variable
-.I POSIXLY_CORRECT
+.Dv POSIXLY_CORRECT
 is defined.
 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.
 Specify an alternate list of files containing magic numbers.
 This can be a single file, or a colon-separated list of files.
 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.
 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.
 Force stdout to be flushed after checking each file.
 This is only useful if checking a list of files.
 This is only useful if checking a list of files.
 It is intended to be used by programs that want filetype output from a pipe.
 It 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.
 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
 On systems that support
-.BR utime (2)
+.Xr utime 2
 or
 or
-.BR utimes(2),
+.Xr utimes 2 ,
 attempt to preserve the access time of files analyzed, to pretend that
 attempt to preserve the access time of files analyzed, to pretend that
-.BR file (2)
+.Nm
 never read them.
 never read them.
-.TP 8
-.B "\-r, \-\-raw"
+.It Fl r , -raw
 Don't translate unprintable characters to \eooo.
 Don't translate unprintable characters to \eooo.
 Normally
 Normally
-.B file
+.Nm
 translates unprintable characters to their octal representation.
 translates unprintable characters to their octal representation.
-.TP 8
-.B "\-s, \-\-special\-files"
+.It Fl s , -special-files
 Normally,
 Normally,
-.B file
+.Nm
 only attempts to read and determine the type of argument files which
 only attempts to read and determine the type of argument files which
-.BR stat (2)
+.Xr stat 2
 reports are ordinary files.
 reports are ordinary files.
 This prevents problems, because reading special files may have peculiar
 This prevents problems, because reading special files may have peculiar
 consequences.
 consequences.
 Specifying the
 Specifying the
-.BR \-s
+.Fl s
 option causes
 option causes
-.B file
+.Nm
 to also read argument files which are block or character special files.
 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
 This is useful for determining the filesystem types of the data in raw
 disk partitions, which are block special files.
 disk partitions, which are block special files.
 This option also causes
 This option also causes
-.B file
+.Nm
 to disregard the file size as reported by
 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.
 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.
 Print the version of the program and exit.
-.TP 8
-.B "\-z, \-\-uncompress"
+.It Fl z , -uncompress
 Try to look inside compressed files.
 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.
 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.
 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
 Default compiled list of magic numbers
-.TP
-.I __MAGIC__
+.It Pa __MAGIC__
 Default list of magic numbers
 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
 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
 The environment variable
-.B MAGIC
+.Dv MAGIC
 can be used to set the default magic number file name.
 can be used to set the default magic number file name.
 If that variable is set, then
 If that variable is set, then
-.B file
+.Nm
 will not attempt to open
 will not attempt to open
-.B $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.
 The environment variable
 The environment variable
-.B POSIXLY_CORRECT
+.Dv POSIXLY_CORRECT
 controls (on systems that support symbolic links), if
 controls (on systems that support symbolic links), if
-.B file
+.Nm
 will attempt to follow symlinks or not. If set, then
 will attempt to follow symlinks or not. If set, then
-.B file
+.Nm
 follows symlink, otherwise it does not. This is also controlled
 follows symlink, otherwise it does not. This is also controlled
 by the
 by the
-.B L
+.Fl L
 and
 and
-.B h
+.Fl h
 options.
 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
 This program is believed to exceed the System V Interface Definition
 of FILE(CMD), as near as one can determine from the vague language
 of FILE(CMD), as near as one can determine from the vague language
 contained therein. 
 contained therein. 
@@ -330,66 +364,74 @@ Its behavior is mostly compatible with the System V program of the same name.
 This version knows more magic, however, so it will produce
 This version knows more magic, however, so it will produce
 different (albeit more accurate) output in many cases. 
 different (albeit more accurate) output in many cases. 
 .\" URL: http://www.opengroup.org/onlinepubs/009695399/utilities/file.html
 .\" URL: http://www.opengroup.org/onlinepubs/009695399/utilities/file.html
-.PP
+.Pp
 The one significant difference 
 The one significant difference 
 between this version and System V
 between this version and System V
 is that this version treats any white space
 is that this version treats any white space
 as a delimiter, so that spaces in pattern strings must be escaped.
 as a delimiter, so that spaces in pattern strings must be escaped.
 For example,
 For example,
-.br
+.Bd -literal -offset indent 
 >10	string	language impress\ 	(imPRESS data)
 >10	string	language impress\ 	(imPRESS data)
-.br
+.Ed
+.Pp
 in an existing magic file would have to be changed to
 in an existing magic file would have to be changed to
-.br
+.Bd -literal -offset indent 
 >10	string	language\e impress	(imPRESS data)
 >10	string	language\e impress	(imPRESS data)
-.br
+.Ed
+.Pp
 In addition, in this version, if a pattern string contains a backslash,
 In addition, in this version, if a pattern string contains a backslash,
 it must be escaped.
 it must be escaped.
 For example
 For example
-.br
+.Bd -literal -offset indent 
 0	string		\ebegindata	Andrew Toolkit document
 0	string		\ebegindata	Andrew Toolkit document
-.br
+.Ed
+.Pp
 in an existing magic file would have to be changed to
 in an existing magic file would have to be changed to
-.br
+.Bd -literal -offset indent 
 0	string		\e\ebegindata	Andrew Toolkit document
 0	string		\e\ebegindata	Andrew Toolkit document
-.br
-.PP
+.Ed
+.Pp
 SunOS releases 3.2 and later from Sun Microsystems include a
 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.
 command derived from the System V one, but with some extensions.
 My version differs from Sun's only in minor ways.
 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,
 for example,
-.br
+.Bd -literal -offset indent 
 >16	long&0x7fffffff	>0		not stripped
 >16	long&0x7fffffff	>0		not stripped
-.SH MAGIC DIRECTORY
+.Ed
+.Sh MAGIC DIRECTORY
 The magic file entries have been collected from various sources,
 The magic file entries have been collected from various sources,
 mainly USENET, and contributed by various authors.
 mainly USENET, and contributed by various authors.
 Christos Zoulas (address below) will collect additional
 Christos Zoulas (address below) will collect additional
 or corrected magic file entries.
 or corrected magic file entries.
 A consolidation of magic file entries 
 A consolidation of magic file entries 
 will be distributed periodically.
 will be distributed periodically.
-.PP
+.Pp
 The order of entries in the magic file is significant.
 The order of entries in the magic file is significant.
 Depending on what system you are using, the order that
 Depending on what system you are using, the order that
 they are put together may be incorrect.
 they are put together may be incorrect.
 If your old
 If your old
-.B file
+.Nm
 command uses a magic file,
 command uses a magic file,
 keep the old magic file around for comparison purposes
 keep the old magic file around for comparison purposes
 (rename it to 
 (rename it to 
-.IR __MAGIC__.orig ).
-.SH EXAMPLES
-.nf
+.Pa __MAGIC__.orig ).
+.Sh EXAMPLES
+.Bd -literal -offset indent 
 $ file file.c file /dev/{wd0a,hda}
 $ file file.c file /dev/{wd0a,hda}
 file.c:   C program text
 file.c:   C program text
 file:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
 file:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
           dynamically linked (uses shared libs), stripped
           dynamically linked (uses shared libs), stripped
 /dev/wd0a: block special (0/0)
 /dev/wd0a: block special (0/0)
 /dev/hda: block special (3/0)
 /dev/hda: block special (3/0)
+
 $ file -s /dev/wd0{b,d}
 $ file -s /dev/wd0{b,d}
 /dev/wd0b: data
 /dev/wd0b: data
 /dev/wd0d: x86 boot sector
 /dev/wd0d: x86 boot sector
+
 $ file -s /dev/hda{,1,2,3,4,5,6,7,8,9,10}
 $ file -s /dev/hda{,1,2,3,4,5,6,7,8,9,10}
 /dev/hda:   x86 boot sector
 /dev/hda:   x86 boot sector
 /dev/hda1:  Linux/i386 ext2 filesystem
 /dev/hda1:  Linux/i386 ext2 filesystem
@@ -406,129 +448,147 @@ $ file -s /dev/hda{,1,2,3,4,5,6,7,8,9,10}
 $ file -i file.c file /dev/{wd0a,hda}
 $ file -i file.c file /dev/{wd0a,hda}
 file.c:      text/x-c
 file.c:      text/x-c
 file:        application/x-executable, dynamically linked (uses shared libs),
 file:        application/x-executable, dynamically linked (uses shared libs),
-not stripped
+	     not stripped
 /dev/hda:    application/x-not-regular-file
 /dev/hda:    application/x-not-regular-file
 /dev/wd0a:   application/x-not-regular-file
 /dev/wd0a:   application/x-not-regular-file
 
 
-.fi
-.SH HISTORY
+.Ed
+.Sh HISTORY
 There has been a 
 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).
 (man page dated November, 1973).
 The System V version introduced one significant major change:
 The System V version introduced one significant major change:
 the external list of magic number types.
 the external list of magic number types.
 This slowed the program down slightly but made it a lot more flexible.
 This slowed the program down slightly but made it a lot more flexible.
-.PP
+.Pp
 This program, based on the System V version,
 This program, based on the System V version,
 was written by Ian Darwin <ian@darwinsys.com>
 was written by Ian Darwin <ian@darwinsys.com>
 without looking at anybody else's source code.
 without looking at anybody else's source code.
-.PP
+.Pp
 John Gilmore revised the code extensively, making it better than
 John Gilmore revised the code extensively, making it better than
 the first version.
 the first version.
 Geoff Collyer found several inadequacies
 Geoff Collyer found several inadequacies
 and provided some magic file entries.
 and provided some magic file entries.
 Contributions by the `&' operator by Rob McMahon, cudcv@warwick.ac.uk, 1989.
 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.
 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
 Primary development and maintenance from 1990 to the present by
 Christos Zoulas (christos@astron.com).
 Christos Zoulas (christos@astron.com).
-.PP
+.Pp
 Altered by Chris Lowth, chris@lowth.com, 2000:
 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.
 magic file and internal logic.
-.PP
+.Pp
 Altered by Eric Fischer (enf@pobox.com), July, 2000,
 Altered by Eric Fischer (enf@pobox.com), July, 2000,
 to identify character codes and attempt to identify the languages
 to identify character codes and attempt to identify the languages
 of non-ASCII files.
 of non-ASCII files.
-.PP
+.Pp
 The list of contributors to the "Magdir" directory (source for the
 The list of contributors to the "Magdir" directory (source for the
-.I __MAGIC__
+.Pa __MAGIC__
 file) is too long to include here.
 file) is too long to include here.
 You know who you are; thank you.
 You know who you are; thank you.
-.SH LEGAL NOTICE
+.Sh LEGAL NOTICE
 Copyright (c) Ian F. Darwin, Toronto, Canada, 1986-1999.
 Copyright (c) Ian F. Darwin, Toronto, Canada, 1986-1999.
 Covered by the standard Berkeley Software Distribution copyright; see the file
 Covered by the standard Berkeley Software Distribution copyright; see the file
 LEGAL.NOTICE in the source distribution.
 LEGAL.NOTICE in the source distribution.
-.PP
+.Pp
 The files
 The files
-.I tar.h
+.Dv tar.h
 and
 and
-.I is_tar.c
+.Dv is_tar.c
 were written by John Gilmore from his public-domain
 were written by John Gilmore from his public-domain
-.B tar
+.Xr tar 1
 program, and are not covered by the above license.
 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
 There must be a better way to automate the construction of the Magic
 file from all the glop in Magdir.
 file from all the glop in Magdir.
 What is it?
 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,
 uses several algorithms that favor speed over accuracy,
 thus it can be misled about the contents of
 thus it can be misled about the contents of
 text
 text
 files.
 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.
 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
 Their use of
-.SM "ASCII TAB"
+.Dv ASCII TAB
 as a field delimiter is ugly and makes
 as a field delimiter is ugly and makes
 it hard to edit the files, but is entrenched.
 it hard to edit the files, but is entrenched.
-.PP
+.Pp
 It might be advisable to allow upper-case letters in keywords
 It might be advisable to allow upper-case letters in keywords
 for e.g.,
 for e.g.,
-.BR troff (1)
+.Xr troff 1
 commands vs man page macros.
 commands vs man page macros.
 Regular expression support would make this easy.
 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.
 appear indented at the start of line.
 Regular expression support would make this easy.
 Regular expression support would make this easy.
-.PP
+.Pp
 The list of keywords in 
 The list of keywords in 
-.I ascmagic
+.Dv ascmagic
 probably belongs in the Magic file.
 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.
 Complain about conflicts in the magic file entries.
 Make a rule that the magic entries sort based on file offset rather
 Make a rule that the magic entries sort based on file offset rather
 than position within the magic file?
 than position within the magic file?
-.PP
+.Pp
 The program should provide a way to give an estimate 
 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
 Still, if the others don't pan out, it should be possible to use the
 first guess.  
 first guess.  
-.PP
+.Pp
 This program is slower than some vendors' file commands.
 This program is slower than some vendors' file commands.
 The new support for multiple character codes makes it even slower.
 The new support for multiple character codes makes it even slower.
-.PP
+.Pp
 This manual page, and particularly this section, is too long.
 This manual page, and particularly this section, is too long.
-.SH AVAILABILITY
+.Sh AVAILABILITY
 You can obtain the original author's latest version by anonymous FTP
 You can obtain the original author's latest version by anonymous FTP
 on
 on
-.B ftp.astron.com
+.Dv ftp.astron.com
 in the directory
 in the directory
-.I /pub/file/file-X.YZ.tar.gz
+.Dv /pub/file/file-X.YZ.tar.gz

+ 20 - 0
doc/libmagic.man

@@ -104,6 +104,26 @@ Don't translate unprintable characters to a \eooo octal representation.
 .It Dv MAGIC_ERROR
 .It Dv MAGIC_ERROR
 Treat operating system errors while trying to open files and follow symlinks
 Treat operating system errors while trying to open files and follow symlinks
 as real errors, instead of printing them in the magic buffer.
 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
 .El
 .Pp
 .Pp
 The
 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.
 .\" 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
 This manual page documents the format of the magic file as
 used by the
 used by the
-.BR file (__CSECTION__)
+.Xr file __CSECTION__
 command, version __VERSION__.
 command, version __VERSION__.
 The
 The
-.BR file
+.Xr file __CSECTION__
 command identifies the type of a file using,
 command identifies the type of a file using,
 among other tests,
 among other tests,
 a test for whether the file begins with a certain
 a test for whether the file begins with a certain
-.IR "magic number" .
+.Dq "magic number" .
 The file
 The file
-.I __MAGIC__
+.Pa __MAGIC__
 specifies what magic numbers are to be tested for,
 specifies what magic numbers are to be tested for,
 what message to print if a particular magic number is found,
 what message to print if a particular magic number is found,
 and additional information to extract from the file.
 and additional information to extract from the file.
-.PP
+.Pp
 Each line of the file specifies a test to be performed.
 Each line of the file specifies a test to be performed.
 A test compares the data starting at a particular offset
 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
 in the file with a 1-byte, 2-byte, or 4-byte numeric value or
 a string.
 a string.
 If the test succeeds, a message is printed.
 If the test succeeds, a message is printed.
 The line consists of the following fields:
 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
 A number specifying the offset, in bytes, into the file of the data
 which is to be tested.
 which is to be tested.
-.IP type
+.It Dv type
 The type of the data to be tested.
 The type of the data to be tested.
 The possible values are:
 The possible values are:
-.RS
-.IP byte \w'message'u+2n
+.Bl -tag -width ".Dv lestring16"
+.It Dv byte
 A one-byte value.
 A one-byte value.
-.IP short
+.It Dv short
 A two-byte value (on most systems) in this machine's native byte order.
 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.
 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.
 An eight-byte value (on most systems) in this machine's native byte order.
-.IP string
+.It Dv string
 A string of bytes.
 A string of bytes.
 The string type specification can be optionally followed
 The string type specification can be optionally followed
 by /[Bbc]*.
 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.
 contain at least one whitespace character.
 If the magic has
 If the magic has
-.I n
+.Dv n
 consecutive blanks, the target needs at least
 consecutive blanks, the target needs at least
-.I n
+.Dv n
 consecutive blanks to match.
 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
 characters in the magic match both lower and upper case characters in the
 targer, whereas upper case characters in the magic, only much uppercase
 targer, whereas upper case characters in the magic, only much uppercase
 characters in the target.
 characters in the target.
-.IP pstring
+.It Dv pstring
 A pascal style string where the first byte is interpreted as the an
 A pascal style string where the first byte is interpreted as the an
 unsigned length. The string is not NUL terminated.
 unsigned length. The string is not NUL terminated.
-.IP date
+.It Dv date
 A four-byte value interpreted as a UNIX date.
 A four-byte value interpreted as a UNIX date.
-.IP qdate
+.It Dv qdate
 A eight-byte value interpreted as a UNIX date.
 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
 A four-byte value interpreted as a UNIX-style date, but interpreted as
 local time rather than UTC.
 local time rather than UTC.
-.IP qldate
+.It Dv qldate
 An eight-byte value interpreted as a UNIX-style date, but interpreted as
 An eight-byte value interpreted as a UNIX-style date, but interpreted as
 local time rather than UTC.
 local time rather than UTC.
-.IP beshort
+.It Dv beshort
 A two-byte value (on most systems) in big-endian byte order.
 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.
 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.
 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,
 A four-byte value (on most systems) in big-endian byte order,
 interpreted as a Unix date.
 interpreted as a Unix date.
-.IP beqdate
+.It Dv beqdate
 An eight-byte value (on most systems) in big-endian byte order,
 An eight-byte value (on most systems) in big-endian byte order,
 interpreted as a Unix date.
 interpreted as a Unix date.
-.IP beldate
+.It Dv beldate
 A four-byte value (on most systems) in big-endian byte order,
 A four-byte value (on most systems) in big-endian byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
 than UTC.
-.IP beqldate
+.It Dv beqldate
 An eight-byte value (on most systems) in big-endian byte order,
 An eight-byte value (on most systems) in big-endian byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
 than UTC.
-.IP bestring16
+.It Dv bestring16
 A two-byte unicode (UCS16) string in big-endian byte order.
 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.
 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.
 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.
 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,
 A four-byte value (on most systems) in little-endian byte order,
 interpreted as a UNIX date.
 interpreted as a UNIX date.
-.IP leqdate
+.It Dv leqdate
 An eight-byte value (on most systems) in little-endian byte order,
 An eight-byte value (on most systems) in little-endian byte order,
 interpreted as a UNIX date.
 interpreted as a UNIX date.
-.IP leldate
+.It Dv leldate
 A four-byte value (on most systems) in little-endian byte order,
 A four-byte value (on most systems) in little-endian byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
 than UTC.
-.IP leqldate
+.It Dv leqldate
 An eight-byte value (on most systems) in little-endian byte order,
 An eight-byte value (on most systems) in little-endian byte order,
 interpreted as a UNIX-style date, but interpreted as local time rather
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
 than UTC.
-.IP lestring16
+.It Dv lestring16
 A two-byte unicode (UCS16) string in little-endian byte order.
 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.
 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,
 A four-byte value (on most systems) in middle-endian (PDP-11) byte order,
 interpreted as a UNIX date.
 interpreted as a UNIX date.
-.IP meldate
+.It Dv meldate
 A four-byte value (on most systems) in middle-endian (PDP-11) byte order,
 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
 interpreted as a UNIX-style date, but interpreted as local time rather
 than UTC.
 than UTC.
-.IP regex
+.It Dv regex
 A regular expression match in extended POSIX regular expression syntax
 A regular expression match in extended POSIX regular expression syntax
 (much like egrep).
 (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
 lines, where
-.B N
+.Dv N
 is the given offset, thus it
 is the given offset, thus it
 is only useful for (single-byte encoded) text.
 is only useful for (single-byte encoded) text.
-.B ^
+.Dv ^
 and
 and
-.B $
+.Dv $
 will match the beginning and end of individual lines, respectively,
 will match the beginning and end of individual lines, respectively,
 not beginning and end of file.
 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
 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).
 which specifies how many matches shall be attempted (the range).
 This is suitable for searching larger binary expressions with variable
 This is suitable for searching larger binary expressions with variable
 offsets, using
 offsets, using
-.B \e
+.Dv \e
 escapes for special characters.
 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
 The numeric types may optionally be followed by
-.B &
+.Dv &
 and a numeric value,
 and a numeric value,
 to specify that the value is to be AND'ed with the
 to specify that the value is to be AND'ed with the
 numeric value before any comparisons are done.
 numeric value before any comparisons are done.
 Prepending a
 Prepending a
-.B u
+.Dv u
 to the type indicates that ordered comparisons should be unsigned.
 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.
 The value to be compared with the value from the file.
 If the type is
 If the type is
 numeric, this value
 numeric, this value
 is specified in C form; if it is a string, it is specified as a C string
 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).
 with the usual escapes permitted (e.g. \en for new-line).
-.IP
+.Pp
 Numeric values
 Numeric values
 may be preceded by a character indicating the operation to be performed.
 may be preceded by a character indicating the operation to be performed.
 It may be
 It may be
-.BR = ,
+.Dv = ,
 to specify that the value from the file must equal the specified value,
 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
 to specify that the value from the file must be less than the specified
 value,
 value,
-.BR > ,
+.Dv > ,
 to specify that the value from the file must be greater than the specified
 to specify that the value from the file must be greater than the specified
 value,
 value,
-.BR & ,
+.Dv & ,
 to specify that the value from the file must have set all of the bits
 to specify that the value from the file must have set all of the bits
 that are set in the specified value,
 that are set in the specified value,
-.BR ^ ,
+.Dv ^ ,
 to specify that the value from the file must have clear any of the bits
 to specify that the value from the file must have clear any of the bits
 that are set in the specified value, or
 that are set in the specified value, or
-.BR ~ ,
+.Dv ~ ,
 the value specified after is negated before tested.
 the value specified after is negated before tested.
-.BR x ,
+.Dv x ,
 to specify that any value will match.
 to specify that any value will match.
 If the character is omitted, it is assumed to be
 If the character is omitted, it is assumed to be
-.BR = .
+.Dv = .
 For all tests except
 For all tests except
-.B string
+.Em string
 and
 and
-.B regex,
+.Em regex,
 operation
 operation
-.BR !
+.Dv !
 specifies that the line matches if the test does
 specifies that the line matches if the test does
-.B not
+.Em not
 succeed.
 succeed.
-.IP
+.Pp
 Numeric values are specified in C form; e.g.
 Numeric values are specified in C form; e.g.
-.B 13
+.Dv 13
 is decimal,
 is decimal,
-.B 013
+.Dv 013
 is octal, and
 is octal, and
-.B 0x13
+.Dv 0x13
 is hexadecimal.
 is hexadecimal.
-.IP
+.Pp
 For string values, the byte string from the
 For string values, the byte string from the
 file must match the specified byte string.
 file must match the specified byte string.
 The operators
 The operators
-.BR = ,
-.B <
+.Dv = ,
+.Dv <
 and
 and
-.B >
+.Dv >
 (but not
 (but not
-.BR & )
+.Dv & )
 can be applied to strings.
 can be applied to strings.
 The length used for matching is that of the string argument
 The length used for matching is that of the string argument
 in the magic file.
 in the magic file.
 This means that a line can match any string, and
 This means that a line can match any string, and
 then presumably print that string, by doing
 then presumably print that string, by doing
-.B >\e0
+.Em >\e0
 (because all strings are greater than the null string).
 (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
 The message to be printed if the comparison succeeds.  If the string
 contains a
 contains a
-.BR printf (3)
+.Xr printf 3
 format specification, the value from the file (with any specified masking
 format specification, the value from the file (with any specified masking
 performed) is printed using the message as the format string.
 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
 Some file formats contain additional information which is to be printed
 along with the file type or need additional tests to determine the true
 along with the file type or need additional tests to determine the true
 file type.
 file type.
 These additional tests are introduced by one or more
 These additional tests are introduced by one or more
-.B >
+.Em >
 characters preceding the offset.
 characters preceding the offset.
 The number of
 The number of
-.B >
+.Em >
 on the line indicates the level of the test; a line with no
 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.
 at the beginning is considered to be at level 0.
 Tests are arranged in a tree-like hierarchy:
 Tests are arranged in a tree-like hierarchy:
 If a the test on a line at level
 If a the test on a line at level
-.IB n
+.Em n
 succeeds, all following tests at level
 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
 are performed, and the messages printed if the tests succeed, untile a line
 with level
 with level
-.IB n
+.Em n
 (or less) appears.
 (or less) appears.
 For more complex files, one can use empty messages to get just the
 For more complex files, one can use empty messages to get just the
 "if/then" effect, in the following way:
 "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
 Offsets do not need to be constant, but can also be read from the file
 being examined.
 being examined.
 If the first character following the last
 If the first character following the last
-.B >
+.Em >
 is a
 is a
-.B (
+.Em (
 then the string after the parenthesis is interpreted as an indirect offset.
 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
 That means that the number after the parenthesis is used as an offset in
 the file.
 the file.
 The value at that offset is read, and is used again as an offset
 The value at that offset is read, and is used again as an offset
 in the file.
 in the file.
 Indirect offsets are of the form:
 Indirect offsets are of the form:
-.BI (( x [.[bslBSL]][+\-][ y ]).
+.Em (( x [.[bslBSL]][+\-][ y ]).
 The value of
 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
 is used as an offset in the file. A byte, short or long is read at that offset
 depending on the
 depending on the
-.B [bslBSLm]
+.Em [bslBSLm]
 type specifier.
 type specifier.
 The capitalized types interpret the number as a big endian
 The capitalized types interpret the number as a big endian
 value, whereas the small letter versions interpret the number as a little
 value, whereas the small letter versions interpret the number as a little
 endian value;
 endian value;
 the
 the
-.B m
+.Em m
 type interprets the number as a middle endian (PDP-11) value.
 type interprets the number as a middle endian (PDP-11) value.
 To that number the value of
 To that number the value of
-.I y
+.Em y
 is added and the result is used as an offset in the file.
 is added and the result is used as an offset in the file.
 The default type if one is not specified is long.
 The default type if one is not specified is long.
-.PP
+.Pp
 That way variable length structures can be examined:
 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
 This strategy of examining has one drawback: You must make sure that
 you eventually print something, or users may get empty output (like, when
 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)
 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
 If this indirect offset cannot be used as-is, there are simple calculations
 possible: appending
 possible: appending
-.BI [+-*/%&|^]<number>
+.Em [+-*/%&|^]<number>
 inside parentheses allows one to modify
 inside parentheses allows one to modify
 the value read from the file before it is used as an offset:
 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
 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
 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
 specify an offset relative to the end of the last up-level field using
-.BI &
+.Sq &
 as a prefix to the offset:
 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:
 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:
 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!
 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
 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,
 second value in a parenthesized expression can be taken from the file itself,
 using another set of parentheses. Note that this additional indirect offset
 using another set of parentheses. Note that this additional indirect offset
 is always relative to the start of the main 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
 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
 and
-.I meldate
+.Dv meldate
 are system-dependent; perhaps they should be specified as a number
 are system-dependent; perhaps they should be specified as a number
 of bytes (2B, 4B, etc),
 of bytes (2B, 4B, etc),
 since the files being recognized typically come from
 since the files being recognized typically come from
 a system on which the lengths are invariant.
 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.
 \- the command that reads this file.
 .\"
 .\"
 .\" From: guy@sun.uucp (Guy Harris)
 .\" 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.
 .\" the changes I posted to the S5R2 version.
 .\"
 .\"
 .\" Modified for Ian Darwin's version of the file command.
 .\" 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
 # 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:
 # Add any locally observed files here.  Remember:
 # text if readable, executable if runnable binary, data if unreadable.
 # 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
 #>3     byte&0x03       3              \b, NR: CCIT J.17
 
 
 # MPA, M1A
 # 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
 # GRR the original test are too common for many DOS files, so test 32 <= kbits <= 448
 0	beshort&0xFFFE		0xFFFE	
 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
 # rate
 >>>2      byte&0xF0       0x10           \b,  32 kBits
 >>>2      byte&0xF0       0x10           \b,  32 kBits
 >>>2      byte&0xF0       0x20           \b,  64 kBits
 >>>2      byte&0xF0       0x20           \b,  64 kBits

+ 1 - 1
magic/Magdir/archive

@@ -478,7 +478,7 @@
 0	string		HPAK		HPACK archive data
 0	string		HPAK		HPACK archive data
 
 
 # JAM Archive volume format, by Dmitry.Kohmanyuk@UA.net
 # 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
 >7	string		>\0			version %.4s
 >0x26	byte		=0x27			-
 >0x26	byte		=0x27			-
 >>0x2b	string          >\0			label %.11s,
 >>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
 # Since I saw only eqf files with version v1.1 I think that it's OK
 >23	string	x	\b%.4s
 >23	string	x	\b%.4s
 # .preset
 # .preset
-0	string	\[Equalizer\ preset\]	XMMS equalizer preset
+0	string	[Equalizer\ preset]	XMMS equalizer preset
 # .m3u
 # .m3u
-0	string	\#EXTM3U	M3U playlist
+0	string	#EXTM3U			M3U playlist
 # .pls
 # .pls
-0	string	\[playlist\]	PLS playlist
+0	string	[playlist]		PLS playlist
 # licq.conf
 # licq.conf
-1	string	\[licq\]	LICQ configuration file
+1	string	[licq]			LICQ configuration file
 
 
 # Atari ST audio files by Dirk Jagdmann <doj@cubic.org>
 # Atari ST audio files by Dirk Jagdmann <doj@cubic.org>
 0	string		ICE!		SNDH Atari ST music
 0	string		ICE!		SNDH Atari ST music
@@ -545,3 +545,10 @@
 >>27    byte            113     \b, Alpha 1.13
 >>27    byte            113     \b, Alpha 1.13
 >>27    byte            114     \b, Beta 1.14
 >>27    byte            114     \b, Beta 1.14
 >>27    byte            115     \b, Alpha 1.15
 >>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
 # The inverted index functionality was added some time betwen
 # versions 11 and 15, so look for -q if version is above 14:
 # versions 11 and 15, so look for -q if version is above 14:
 >7	string		>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		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>
 # From: Serge van den Boom <svdb@stack.nl>
 0	string		\x01ZZZZZ\x01	3DO "Opera" file system
 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
 16	string		MIT-MAGIC-COOKIE-1	X11 Xauthority data
 17	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
 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
 0	string	VimCrypt~	Vim encrypted file data
 # Vi IMproved Swap file
 # Vi IMproved Swap file
 # by Sven Wegener <swegener@gentoo.org>
 # 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	&0x000400	HaL R1 Extensions Required,
 >>>36	belong&0xffff00	&0x000800	Sun UltraSPARC3 Extensions Required,
 >>>36	belong&0xffff00	&0x000800	Sun UltraSPARC3 Extensions Required,
 >>18	beshort		20		PowerPC or cisco 4500,
 >>18	beshort		20		PowerPC or cisco 4500,
->>18	beshort		21		cisco 7500,
+>>18	beshort		21		64-bit PowerPC or cisco 7500,
 >>18	beshort		22		IBM S/390,
 >>18	beshort		22		IBM S/390,
+>>18	beshort		23		Cell SPU,
 >>18	beshort		24		cisco SVIP,
 >>18	beshort		24		cisco SVIP,
 >>18	beshort		25		cisco 7200,
 >>18	beshort		25		cisco 7200,
 >>18	beshort		36		NEC V800 or cisco 12000,
 >>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
 0	string	\366\366\366\366	PC formatted floppy with no filesystem
 # Sun disk labels
 # Sun disk labels
 # From /usr/include/sun/dklabel.h:
 # 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?
 # Is there a boot block written 1 sector in?
 >512    belong&077777777	0600407	\b, boot block present
 >512    belong&077777777	0600407	\b, boot block present
 # Joerg Jenderek: Smart Boot Manager backup file is 41 byte header + first sectors of disc
 # 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
 >>96	string	read\ error\ while\ reading\ drive	\b, FREE-DOS Beta 0.9 MBR
 >271	string	Operating\ system\ loading 		
 >271	string	Operating\ system\ loading 		
 >>296	string	error\r					\b, SYSLINUX MBR (2.10)
 >>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
 # 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
 >382	string	XOSLLOADXCF			\b, eXtended Operating System Loader
 >6	string	LILO				\b, LInux i386 boot LOader
 >6	string	LILO				\b, LInux i386 boot LOader
 >>120	string	LILO				\b, version 22.3.4 SuSe
 >>120	string	LILO				\b, version 22.3.4 SuSe
 >>172	string	LILO				\b, version 22.5.8 Debian
 >>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			
 >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
 >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		!MS	
 >>3			string		!SYSLINUX
 >>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
 # 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\ 			
 >185	string	FDBOOT\ Version\ 			
 >>204	string	\rNo\ Systemdisk.\ 			
 >>204	string	\rNo\ Systemdisk.\ 			
 >>>220	string	Booting\ from\ harddisk.\n\r		
 >>>220	string	Booting\ from\ harddisk.\n\r		
@@ -251,13 +319,12 @@
 >>>>>>>422	string		x 			\b%-.3s
 >>>>>>>422	string		x 			\b%-.3s
 >>>>>425	ubyte&0xDF	>0			
 >>>>>425	ubyte&0xDF	>0			
 >>>>>>425	string		>\ 			\b.%-.3s
 >>>>>>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			
 >430	string	NTLDR\ fehlt\xFF\r\n			
 >>444	string	Datentr\204gerfehler\xFF\r\n		
 >>444	string	Datentr\204gerfehler\xFF\r\n		
@@ -528,6 +595,90 @@
 >>>>>>>>504	string		x 			\b%-.1s
 >>>>>>>>504	string		x 			\b%-.1s
 >>>>505		ubyte&0xDF	>0			
 >>>>505		ubyte&0xDF	>0			
 >>>>>505	string		x 			\b.%-.3s
 >>>>>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
 # loader end
 # Joerg Jenderek
 # Joerg Jenderek
 >446	ubyte	0			
 >446	ubyte	0			
@@ -658,6 +809,61 @@
 
 
 0x18b	string	OS/2	OS/2 Boot Manager
 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),
 9564	lelong		0x00011954	Unix Fast File system [v1] (little-endian),
 >8404	string		x		last mounted on %s,
 >8404	string		x		last mounted on %s,
 #>9504	ledate		x		last checked at %s,
 #>9504	ledate		x		last checked at %s,
@@ -986,3 +1192,8 @@
 #>>&(&0.b+8)  byte    0x42       OpenVMS backup saveset data
 #>>&(&0.b+8)  byte    0x42       OpenVMS backup saveset data
 #>>>40        lelong  x          (block size %d
 #>>>40        lelong  x          (block size %d
 #>>>49        string  >\0        original name '%s')
 #>>>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
 0	beshort		0x1010		PEX Binary Archive
 
 
-# Tgif files
-0	string	\%TGIF\ x 		Tgif file version %s
-
 # DICOM medical imaging data
 # DICOM medical imaging data
 128	string	DICM			DICOM medical imaging data
 128	string	DICM			DICOM medical imaging data
 
 

+ 1 - 1
magic/Magdir/mathematica

@@ -24,7 +24,7 @@
 
 
 # generic:
 # generic:
 0	string	(*^\r\r::[\011	Mathematica notebook version 2.x
 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	(*^\015			Mathematica notebook version 2.x
 0	string	(*^\n\r\n\r::[\011	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
 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
 # mime:  file(1) magic for MIME encoded files
 #
 #
-0	string		Content-Type:\
+0	string		Content-Type:\ 
 >14	string		>\0		%s
 >14	string		>\0		%s
 0	string		Content-Type:
 0	string		Content-Type:
 >13	string		>\0		%s
 >13	string		>\0		%s

+ 2 - 2
magic/Magdir/mips

@@ -165,8 +165,8 @@
 0	string	WNGZWZSS	Wingz spreadsheet
 0	string	WNGZWZSS	Wingz spreadsheet
 0	string	WNGZWZHP	Wingz help file
 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
 # GLF is OpenGL stream encoding
 0	string	glfHeadMagic();		GLF_TEXT
 0	string	glfHeadMagic();		GLF_TEXT
 4	belong	0x7d000000		GLF_BINARY_LSB_FIRST
 4	belong	0x7d000000		GLF_BINARY_LSB_FIRST

+ 2 - 2
magic/Magdir/misctools

@@ -2,8 +2,8 @@
 # misctools:  file(1) magic for miscelanous UNIX tools.
 # misctools:  file(1) magic for miscelanous UNIX tools.
 #
 #
 0	string	%%!!			X-Post-It-Note text
 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>
 # From: Alex Beregszaszi <alex@fsn.hu>
 4	string	gtktalog		GNOME Catalogue (gtktalog)
 4	string	gtktalog		GNOME Catalogue (gtktalog)

+ 1 - 1
magic/Magdir/msdos

@@ -14,7 +14,7 @@
 
 
 # OS/2 batch files are REXX. the second regex is a bit generic, oh well
 # 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
 # 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
 100 regex/c =^\\s*say\ ['"] OS/2 REXX batch file text
 
 
 0	leshort		0x14c	MS Windows COFF Intel 80386 object file
 0	leshort		0x14c	MS Windows COFF Intel 80386 object file

+ 1 - 1
magic/Magdir/os2

@@ -6,7 +6,7 @@
 # Provided 1998/08/22 by
 # Provided 1998/08/22 by
 # David Mediavilla <davidme.news@REMOVEIFNOTSPAMusa.net>
 # David Mediavilla <davidme.news@REMOVEIFNOTSPAMusa.net>
 1	string	InternetShortcut	MS Windows 95 Internet shortcut text
 1	string	InternetShortcut	MS Windows 95 Internet shortcut text
->24	string	>\			(URL=<%s>)
+>24	string	>\ 			(URL=<%s>)
 
 
 # OS/2 URL objects
 # OS/2 URL objects
 # Provided 1998/08/22 by
 # Provided 1998/08/22 by

+ 12 - 4
magic/Magdir/perl

@@ -13,10 +13,18 @@
 0	string		eval\ "exec\ /usr/local/bin/perl	perl script text executable
 0	string		eval\ "exec\ /usr/local/bin/perl	perl script text executable
 0	string		eval\ '(exit\ $?0)'\ &&\ eval\ 'exec	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
 # Perl POD documents
 # From: Tom Hukins <tom@eborcom.com>
 # From: Tom Hukins <tom@eborcom.com>

+ 2 - 1
magic/Magdir/sgml

@@ -12,8 +12,9 @@
 # Extensible markup language (XML), a subset of SGML
 # Extensible markup language (XML), a subset of SGML
 # from Marc Prud'hommeaux (marc@apocalypse.org)
 # from Marc Prud'hommeaux (marc@apocalypse.org)
 0	string/cb	\<?xml			XML document text
 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
+0	string		\<?xml\ version='	XML
 >15	string		>\0			%.3s document text
 >15	string		>\0			%.3s document text
 >>23	string		\<xsl:stylesheet	(XSL stylesheet)
 >>23	string		\<xsl:stylesheet	(XSL stylesheet)
 >>24	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]
 >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
 0	string		This\ is\ Info\ file	GNU Info text
 
 
 # TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com)
 # 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>
 # Tex document, from Hendrik Scholz <hendrik@scholz.net>
 0   string      \\ifx       TeX document text
 0   string      \\ifx       TeX document text
 
 
 # Index and glossary files
 # 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
 # End of TeX
 
 

+ 1 - 1
magic/Magdir/tgif

@@ -2,5 +2,5 @@
 # file(1) magic for tgif(1) files
 # file(1) magic for tgif(1) files
 # From Hendrik Scholz <hendrik@scholz.net>
 # 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>
 # From: Alex Beregszaszi <alex@fsn.hu>
 # 0	string		exec 		BugOS executable
 # 0	string		exec 		BugOS executable
 # 0	string		pack		BugOS archive
 # 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
 0	string		#!\ /			a
 >3	string		>\0			%s script text executable
 >3	string		>\0			%s script text executable
-0	string		#!\	/		a
+0	string		#!\t/			a
 >3	string		>\0			%s script text executable
 >3	string		>\0			%s script text executable
 0	string		#!/			a
 0	string		#!/			a
 >2	string		>\0			%s script text executable
 >2	string		>\0			%s script text executable

+ 1 - 1
magic/Magdir/wordprocessors

@@ -3,7 +3,7 @@
 # wordprocessors:  file(1) magic fo word processors.
 # wordprocessors:  file(1) magic fo word processors.
 #
 #
 ####### PWP file format used on Smith Corona Personal 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	2	\b, single spaced
 >24	byte	3	\b, 1.5 spaced
 >24	byte	3	\b, 1.5 spaced
 >24	byte	4	\b, double spaced
 >24	byte	4	\b, double spaced

+ 18 - 3
magic/magic.mime

@@ -193,7 +193,12 @@
 0       beshort         0x4De1          audio/MP4A-LATM
 0       beshort         0x4De1          audio/MP4A-LATM
 
 
 # MPEG Layer 3 sound files
 # MPEG Layer 3 sound files
-0       beshort		&0xffe0		audio/mpeg
+# modified by Joerg Jenderek
+# GRR the original test are too common for many DOS files
+# so test 1 <= kbits nibble <= E
+0       beshort		&0xffe0		
+>2	ubyte&0xF0	>0x0F		
+>>2	ubyte&0xF0	<0xE1		audio/mpeg
 #MP3 with ID3 tag
 #MP3 with ID3 tag
 0	string		ID3		audio/mpeg
 0	string		ID3		audio/mpeg
 # Ogg/Vorbis
 # Ogg/Vorbis
@@ -587,6 +592,14 @@
 # RTF - Rich Text Format
 # RTF - Rich Text Format
 0	string		{\\rtf		text/rtf
 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
 # animation:  file(1) magic for animation/movie formats
 #
 #
@@ -674,9 +687,9 @@
 #
 #
 # KDE
 # KDE
 0		string	[KDE\ Desktop\ Entry]	application/x-kdelnk
 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
 # xmcd database file for kscd
-0		string	\#\ xmcd                text/xmcd
+0		string	#\ xmcd                text/xmcd
 
 
 #------------------------------------------------------------------------------
 #------------------------------------------------------------------------------
 # pkgadd:  file(1) magic for SysV R4 PKG Datastreams
 # pkgadd:  file(1) magic for SysV R4 PKG Datastreams
@@ -861,6 +874,8 @@
 # miscellaneous formats
 # miscellaneous formats
 0		string	LZ		application/octet-stream
 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)
 # .EXE formats (Greg Roelofs, newt@uchicago.edu)
 #
 #

+ 1 - 1
magic/magic2mime

@@ -1,6 +1,6 @@
 #! /usr/bin/env perl
 #! /usr/bin/env perl
 # -*- 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)
 # Copyright (c) 1996, 1997 vax@linkdead.paranoia.com (VaX#n8)
 #
 #
 # Usage: echo 'your-file-output-here' | file_to_ctype.pl
 # Usage: echo 'your-file-output-here' | file_to_ctype.pl

+ 427 - 117
src/apprentice.c

@@ -46,7 +46,7 @@
 #endif
 #endif
 
 
 #ifndef	lint
 #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 */
 #endif	/* lint */
 
 
 #define	EATAB {while (isascii((unsigned char) *l) && \
 #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
 #define MAXPATHLEN	1024
 #endif
 #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_entry {
 	struct magic *mp;	
 	struct magic *mp;	
 	uint32_t cont_count;
 	uint32_t cont_count;
 	uint32_t max_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 int hextoint(int);
 private const char *getstr(struct magic_set *, const char *, char *, 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 *,
 private int parse(struct magic_set *, struct magic_entry **, uint32_t *,
     const char *, size_t, int);
     const char *, size_t, int);
 private void eatsize(const char **);
 private void eatsize(const char **);
@@ -154,6 +148,82 @@ main(int argc, char *argv[])
 }
 }
 #endif /* COMPILE_ONLY */
 #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.
  * Handle one file.
@@ -241,7 +311,6 @@ file_delmagic(struct magic *p, int type, size_t entries)
 	}
 	}
 }
 }
 
 
-
 /* const char *fn: list of magic files */
 /* const char *fn: list of magic files */
 protected struct mlist *
 protected struct mlist *
 file_apprentice(struct magic_set *ms, const char *fn, int action)
 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;
 	struct mlist *mlist;
 	static const char mime[] = ".mime";
 	static const char mime[] = ".mime";
 
 
+	init_file_tables();
+
 	if (fn == NULL)
 	if (fn == NULL)
 		fn = getenv("MAGIC");
 		fn = getenv("MAGIC");
 	if (fn == NULL)
 	if (fn == NULL)
@@ -316,6 +387,9 @@ apprentice_magic_strength(const struct magic *m)
 	size_t val = 2 * MULT;	/* baseline strength */
 	size_t val = 2 * MULT;	/* baseline strength */
 
 
 	switch (m->type) {
 	switch (m->type) {
+	case FILE_DEFAULT:	/* make sure this sorts last */
+		return 0;
+
 	case FILE_BYTE:
 	case FILE_BYTE:
 		val += 1 * MULT;
 		val += 1 * MULT;
 		break;
 		break;
@@ -401,6 +475,10 @@ apprentice_magic_strength(const struct magic *m)
 		(void)fprintf(stderr, "Bad relation %c\n", m->reln);
 		(void)fprintf(stderr, "Bad relation %c\n", m->reln);
 		abort();
 		abort();
 	}
 	}
+
+	if (val == 0)	/* ensure we only return 0 for FILE_DEFAULT */
+		val = 1;
+
 	return val;
 	return val;
 }
 }
 
 
@@ -485,6 +563,23 @@ apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
 
 
 #ifndef NOORDER
 #ifndef NOORDER
 	qsort(marray, marraycount, sizeof(*marray), apprentice_sort);
 	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
 #endif
 
 
 	for (i = 0; i < marraycount; i++)
 	for (i = 0; i < marraycount; i++)
@@ -523,7 +618,7 @@ out:
 protected uint64_t
 protected uint64_t
 file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
 file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
 {
 {
-	if (!(m->flag & UNSIGNED))
+	if (!(m->flag & UNSIGNED)) {
 		switch(m->type) {
 		switch(m->type) {
 		/*
 		/*
 		 * Do not remove the casts below.  They are
 		 * 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_LESTRING16:
 		case FILE_REGEX:
 		case FILE_REGEX:
 		case FILE_SEARCH:
 		case FILE_SEARCH:
+		case FILE_DEFAULT:
 			break;
 			break;
 		default:
 		default:
 			if (ms->flags & MAGIC_CHECK)
 			if (ms->flags & MAGIC_CHECK)
@@ -576,9 +672,150 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
 				    m->type);
 				    m->type);
 			return ~0U;
 			return ~0U;
 		}
 		}
+	}
 	return v;
 	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
  * 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, 
 parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp, 
     const char *line, size_t lineno, int action)
     const char *line, size_t lineno, int action)
 {
 {
+#ifdef ENABLE_CONDITIONALS
+	static uint32_t last_cont_level = 0;
+#endif
 	size_t i;
 	size_t i;
 	struct magic_entry *me;
 	struct magic_entry *me;
 	struct magic *m;
 	struct magic *m;
 	const char *l = line;
 	const char *l = line;
 	char *t;
 	char *t;
-	private const char *fops = FILE_OPS;
-	uint64_t val;
+	int op;
 	uint32_t cont_level;
 	uint32_t cont_level;
 
 
 	cont_level = 0;
 	cont_level = 0;
@@ -601,6 +840,12 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
 		++l;		/* step over */
 		++l;		/* step over */
 		cont_level++; 
 		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_CHUNK	(size_t)10
 #define ALLOC_INCR	(size_t)200
 #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;
 			me->max_count = cnt;
 		}
 		}
 		m = &me->mp[me->cont_count++];
 		m = &me->mp[me->cont_count++];
-		memset(m, 0, sizeof(*m));
+		(void)memset(m, 0, sizeof(*m));
 		m->cont_level = cont_level;
 		m->cont_level = cont_level;
 	} else {
 	} else {
 		if (*nmentryp == maxmagic) {
 		if (*nmentryp == maxmagic) {
@@ -648,26 +893,31 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
 			me->max_count = ALLOC_CHUNK;
 			me->max_count = ALLOC_CHUNK;
 		} else
 		} else
 			m = me->mp;
 			m = me->mp;
-		memset(m, 0, sizeof(*m));
+		(void)memset(m, 0, sizeof(*m));
 		m->cont_level = 0;
 		m->cont_level = 0;
 		me->cont_count = 1;
 		me->cont_count = 1;
 	}
 	}
 	m->lineno = lineno;
 	m->lineno = lineno;
 
 
-	if (m->cont_level != 0 && *l == '&') {
+	if (*l == '&') {  /* m->cont_level == 0 checked below. */
                 ++l;            /* step over */
                 ++l;            /* step over */
                 m->flag |= OFFADD;
                 m->flag |= OFFADD;
         }
         }
-	if (m->cont_level != 0 && *l == '(') {
+	if (*l == '(') {
 		++l;		/* step over */
 		++l;		/* step over */
 		m->flag |= INDIR;
 		m->flag |= INDIR;
 		if (m->flag & OFFADD)
 		if (m->flag & OFFADD)
 			m->flag = (m->flag & ~OFFADD) | INDIROFFADD;
 			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 */
 	/* get offset, then skip over it */
 	m->offset = (uint32_t)strtoul(l, &t, 0);
 	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++;
 			l++;
 		}
 		}
+
+		m->in_op = 0;
 		if (*l == '~') {
 		if (*l == '~') {
 			m->in_op |= FILE_OPINVERSE;
 			m->in_op |= FILE_OPINVERSE;
 			l++;
 			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++;
 			l++;
-			break;
 		}
 		}
 		if (*l == '(') {
 		if (*l == '(') {
 			m->in_op |= FILE_OPINDIRECT;
 			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 == '-') {
 		if (isdigit((unsigned char)*l) || *l == '-') {
 			m->in_offset = (int32_t)strtol(l, &t, 0);
 			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;
 			l = t;
 		}
 		}
 		if (*l++ != ')' || 
 		if (*l++ != ')' || 
@@ -769,61 +995,85 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
 				file_magwarn(ms,
 				file_magwarn(ms,
 				    "missing ')' in indirect offset");
 				    "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;
 	EATAB;
+#endif
 
 
 	if (*l == 'u') {
 	if (*l == 'u') {
 		++l;
 		++l;
 		m->flag |= UNSIGNED;
 		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)
 		if (ms->flags & MAGIC_CHECK)
 			file_magwarn(ms, "type `%s' invalid", l);
 			file_magwarn(ms, "type `%s' invalid", l);
 		return -1;
 		return -1;
 	}
 	}
+
 	/* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
 	/* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
 	/* New and improved: ~ & | ^ + - * / % -- exciting, isn't it? */
 	/* New and improved: ~ & | ^ + - * / % -- exciting, isn't it? */
+
+	m->mask_op = 0;
 	if (*l == '~') {
 	if (*l == '~') {
 		if (!IS_STRING(m->type))
 		if (!IS_STRING(m->type))
 			m->mask_op |= FILE_OPINVERSE;
 			m->mask_op |= FILE_OPINVERSE;
+		else if (ms->flags & MAGIC_CHECK)
+			file_magwarn(ms, "'~' invalid for string types");
 		++l;
 		++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;
 			++l;
 			m->mask_op |= op;
 			m->mask_op |= op;
 			val = (uint64_t)strtoull(l, &t, 0);
 			val = (uint64_t)strtoull(l, &t, 0);
 			l = t;
 			l = t;
-			m->mask = file_signextend(ms, m, val);
+			m->num_mask = file_signextend(ms, m, val);
 			eatsize(&l);
 			eatsize(&l);
-		} else {
-			m->mask = 0L;
+		}
+		else if (op == FILE_OPDIVIDE) {
+			int have_count = 0;
 			while (!isspace((unsigned char)*++l)) {
 			while (!isspace((unsigned char)*++l)) {
 				switch (*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;
 					break;
+				}
 				case CHAR_COMPACT_BLANK:
 				case CHAR_COMPACT_BLANK:
-					m->mask |= STRING_COMPACT_BLANK;
+					m->str_flags |= STRING_COMPACT_BLANK;
 					break;
 					break;
 				case CHAR_COMPACT_OPTIONAL_BLANK:
 				case CHAR_COMPACT_OPTIONAL_BLANK:
-					m->mask |=
+					m->str_flags |=
 					    STRING_COMPACT_OPTIONAL_BLANK;
 					    STRING_COMPACT_OPTIONAL_BLANK;
 					break;
 					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:
 				default:
 					if (ms->flags & MAGIC_CHECK)
 					if (ms->flags & MAGIC_CHECK)
 						file_magwarn(ms,
 						file_magwarn(ms,
@@ -831,8 +1081,17 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
 						*l);
 						*l);
 					return -1;
 					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;
 		++l;
 		break;
 		break;
 	default:
 	default:
+  		m->reln = '=';	/* the default relation */
 		if (*l == 'x' && ((isascii((unsigned char)l[1]) && 
 		if (*l == 'x' && ((isascii((unsigned char)l[1]) && 
 		    isspace((unsigned char)l[1])) || !l[1])) {
 		    isspace((unsigned char)l[1])) || !l[1])) {
 			m->reln = *l;
 			m->reln = *l;
 			++l;
 			++l;
-			goto GetDesc;	/* Bill The Cat */
 		}
 		}
-  		m->reln = '=';
 		break;
 		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;
 		return -1;
+
 	/*
 	/*
 	 * TODO finish this macro and start using it!
 	 * TODO finish this macro and start using it!
 	 * #define offsetcheck {if (offset > HOWMANY-1) 
 	 * #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;
 	EATAB;
 	if (l[0] == '\b') {
 	if (l[0] == '\b') {
 		++l;
 		++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.
  * just after the number read.  Return 0 for success, non-zero for failure.
  */
  */
 private int
 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;
 	int slen;
 
 
@@ -1089,7 +1348,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p)
 	case FILE_PSTRING:
 	case FILE_PSTRING:
 	case FILE_REGEX:
 	case FILE_REGEX:
 	case FILE_SEARCH:
 	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 (*p == NULL) {
 			if (ms->flags & MAGIC_CHECK)
 			if (ms->flags & MAGIC_CHECK)
 				file_magwarn(ms, "cannot get string from `%s'",
 				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.
  * Return updated scan pointer as function result.
  */
  */
 private const char *
 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;
 	const char *origs = s;
 	char 	*origp = p;
 	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);
 			file_error(ms, 0, "string too long: `%s'", origs);
 			return NULL;
 			return NULL;
 		}
 		}
-		if(c == '\\') {
+		if (c == '\\') {
 			switch(c = *s++) {
 			switch(c = *s++) {
 
 
 			case '\0':
 			case '\0':
+				if (action == FILE_COMPILE)
+					file_magwarn(ms, "incomplete escape");
 				goto out;
 				goto out;
 
 
+			case '\t':
+				if (action == FILE_COMPILE) {
+					file_magwarn(ms,
+					    "escaped tab found, use \\t instead");
+					action++;
+				}
+				/*FALLTHROUGH*/
 			default:
 			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;
 				*p++ = (char) c;
 				break;
 				break;
 
 
+			case 'a':
+				*p++ = '\a';
+				break;
+
+			case 'b':
+				*p++ = '\b';
+				break;
+
+			case 'f':
+				*p++ = '\f';
+				break;
+
 			case 'n':
 			case 'n':
 				*p++ = '\n';
 				*p++ = '\n';
 				break;
 				break;
@@ -1150,18 +1459,10 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen)
 				*p++ = '\r';
 				*p++ = '\r';
 				break;
 				break;
 
 
-			case 'b':
-				*p++ = '\b';
-				break;
-
 			case 't':
 			case 't':
 				*p++ = '\t';
 				*p++ = '\t';
 				break;
 				break;
 
 
-			case 'f':
-				*p++ = '\f';
-				break;
-
 			case 'v':
 			case 'v':
 				*p++ = '\v';
 				*p++ = '\v';
 				break;
 				break;
@@ -1177,11 +1478,11 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen)
 			case '7':
 			case '7':
 				val = c - '0';
 				val = c - '0';
 				c = *s++;  /* try for 2 */
 				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 */
 					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
 					else
 						--s;
 						--s;
 				}
 				}
@@ -1224,9 +1525,9 @@ hextoint(int c)
 		return -1;
 		return -1;
 	if (isdigit((unsigned char) c))
 	if (isdigit((unsigned char) c))
 		return c - '0';
 		return c - '0';
-	if ((c >= 'a')&&(c <= 'f'))
+	if ((c >= 'a') && (c <= 'f'))
 		return c + 10 - 'a';
 		return c + 10 - 'a';
-	if (( c>= 'A')&&(c <= 'F'))
+	if (( c>= 'A') && (c <= 'F'))
 		return c + 10 - 'A';
 		return c + 10 - 'A';
 	return -1;
 	return -1;
 }
 }
@@ -1250,12 +1551,23 @@ file_showstr(FILE *fp, const char *s, size_t len)
 			if (len-- == 0)
 			if (len-- == 0)
 				break;
 				break;
 		}
 		}
-		if(c >= 040 && c <= 0176)	/* TODO isprint && !iscntrl */
+		if (c >= 040 && c <= 0176)	/* TODO isprint && !iscntrl */
 			(void) fputc(c, fp);
 			(void) fputc(c, fp);
 		else {
 		else {
 			(void) fputc('\\', fp);
 			(void) fputc('\\', fp);
 			switch (c) {
 			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':
 			case '\n':
 				(void) fputc('n', fp);
 				(void) fputc('n', fp);
 				break;
 				break;
@@ -1264,18 +1576,10 @@ file_showstr(FILE *fp, const char *s, size_t len)
 				(void) fputc('r', fp);
 				(void) fputc('r', fp);
 				break;
 				break;
 
 
-			case '\b':
-				(void) fputc('b', fp);
-				break;
-
 			case '\t':
 			case '\t':
 				(void) fputc('t', fp);
 				(void) fputc('t', fp);
 				break;
 				break;
 
 
-			case '\f':
-				(void) fputc('f', fp);
-				break;
-
 			case '\v':
 			case '\v':
 				(void) fputc('v', fp);
 				(void) fputc('v', fp);
 				break;
 				break;
@@ -1536,7 +1840,13 @@ bs1(struct magic *m)
 	m->cont_level = swap2(m->cont_level);
 	m->cont_level = swap2(m->cont_level);
 	m->offset = swap4((uint32_t)m->offset);
 	m->offset = swap4((uint32_t)m->offset);
 	m->in_offset = swap4((uint32_t)m->in_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->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
 #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 */
 #endif /* lint */
 
 
 #ifdef __EMX__
 #ifdef __EMX__

+ 15 - 10
src/ascmagic.c

@@ -49,7 +49,7 @@
 #include "names.h"
 #include "names.h"
 
 
 #ifndef	lint
 #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 */
 #endif	/* lint */
 
 
 typedef unsigned long unichar;
 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_cr = 0;
 	int n_nel = 0;
 	int n_nel = 0;
 
 
-	int last_line_end = -1;
+	size_t last_line_end = (size_t)-1;
 	int has_long_lines = 0;
 	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
 	 * I believe Plan 9 troff allows non-ASCII characters in the names
 	 * of macros, so this test might possibly fail on such a file.
 	 * 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;
 		unichar *tp = ubuf + 1;
 
 
 		while (ISSPC(*tp))
 		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_mime = "text/fortran";
 		subtype = "fortran program";
 		subtype = "fortran program";
 		goto subtype_identified;
 		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! */
 	/* look for tokens from names.h - this is expensive! */
 
 
+	if ((ms->flags & MAGIC_NO_CHECK_TOKENS) != 0)
+		goto subtype_identified;
+
 	i = 0;
 	i = 0;
 	while (i < ulen) {
 	while (i < ulen) {
 		size_t end;
 		size_t end;
@@ -461,7 +465,7 @@ private int
 looks_ascii(const unsigned char *buf, size_t nbytes, unichar *ubuf,
 looks_ascii(const unsigned char *buf, size_t nbytes, unichar *ubuf,
     size_t *ulen)
     size_t *ulen)
 {
 {
-	int i;
+	size_t i;
 
 
 	*ulen = 0;
 	*ulen = 0;
 
 
@@ -480,7 +484,7 @@ looks_ascii(const unsigned char *buf, size_t nbytes, unichar *ubuf,
 private int
 private int
 looks_latin1(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
 looks_latin1(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
 {
 {
-	int i;
+	size_t i;
 
 
 	*ulen = 0;
 	*ulen = 0;
 
 
@@ -500,7 +504,7 @@ private int
 looks_extended(const unsigned char *buf, size_t nbytes, unichar *ubuf,
 looks_extended(const unsigned char *buf, size_t nbytes, unichar *ubuf,
     size_t *ulen)
     size_t *ulen)
 {
 {
-	int i;
+	size_t i;
 
 
 	*ulen = 0;
 	*ulen = 0;
 
 
@@ -519,7 +523,8 @@ looks_extended(const unsigned char *buf, size_t nbytes, unichar *ubuf,
 private int
 private int
 looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
 looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
 {
 {
-	int i, n;
+	size_t i;
+	int n;
 	unichar c;
 	unichar c;
 	int gotone = 0;
 	int gotone = 0;
 
 
@@ -583,7 +588,7 @@ looks_unicode(const unsigned char *buf, size_t nbytes, unichar *ubuf,
     size_t *ulen)
     size_t *ulen)
 {
 {
 	int bigend;
 	int bigend;
-	int i;
+	size_t i;
 
 
 	if (nbytes < 2)
 	if (nbytes < 2)
 		return 0;
 		return 0;
@@ -702,7 +707,7 @@ private unsigned char ebcdic_1047_to_8859[] = {
 private void
 private void
 from_ebcdic(const unsigned char *buf, size_t nbytes, unsigned char *out)
 from_ebcdic(const unsigned char *buf, size_t nbytes, unsigned char *out)
 {
 {
-	int i;
+	size_t i;
 
 
 	for (i = 0; i < nbytes; i++) {
 	for (i = 0; i < nbytes; i++) {
 		out[i] = ebcdic_to_ascii[buf[i]];
 		out[i] = ebcdic_to_ascii[buf[i]];

+ 26 - 19
src/compress.c

@@ -46,12 +46,16 @@
 #ifdef HAVE_SYS_WAIT_H
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #include <sys/wait.h>
 #endif
 #endif
+#if defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#endif
 #ifdef HAVE_LIBZ
 #ifdef HAVE_LIBZ
 #include <zlib.h>
 #include <zlib.h>
 #endif
 #endif
 
 
+
 #ifndef lint
 #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
 #endif
 
 
 private struct {
 private struct {
@@ -74,7 +78,7 @@ private struct {
 	{ "BZh",      3, { "bzip2", "-cd", NULL }, 1 },		/* bzip2-ed */
 	{ "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)
 #define NODATA ((size_t)~0)
 
 
@@ -88,8 +92,8 @@ private size_t uncompressgzipped(struct magic_set *, const unsigned char *,
 #endif
 #endif
 
 
 protected int
 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;
 	unsigned char *newbuf = NULL;
 	size_t i, nsz;
 	size_t i, nsz;
@@ -106,11 +110,11 @@ file_zmagic(struct magic_set *ms, int fd, const unsigned char *buf,
 		    nbytes)) != NODATA) {
 		    nbytes)) != NODATA) {
 			ms->flags &= ~MAGIC_COMPRESS;
 			ms->flags &= ~MAGIC_COMPRESS;
 			rv = -1;
 			rv = -1;
-			if (file_buffer(ms, -1, newbuf, nsz) == -1)
+			if (file_buffer(ms, -1, name, newbuf, nsz) == -1)
 				goto error;
 				goto error;
 			if (file_printf(ms, " (") == -1)
 			if (file_printf(ms, " (") == -1)
 				goto error;
 				goto error;
-			if (file_buffer(ms, -1, buf, nbytes) == -1)
+			if (file_buffer(ms, -1, NULL, buf, nbytes) == -1)
 				goto error;
 				goto error;
 			if (file_printf(ms, ")") == -1)
 			if (file_printf(ms, ")") == -1)
 				goto error;
 				goto error;
@@ -154,9 +158,9 @@ swrite(int fd, const void *buf, size_t n)
  * `safe' read for sockets and pipes.
  * `safe' read for sockets and pipes.
  */
  */
 protected ssize_t
 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
 #ifdef FIONREAD
 	int t = 0;
 	int t = 0;
 #endif
 #endif
@@ -166,11 +170,12 @@ sread(int fd, void *buf, size_t n)
 		goto nocheck;
 		goto nocheck;
 
 
 #ifdef FIONREAD
 #ifdef FIONREAD
-	if ((ioctl(fd, FIONREAD, &t) < 0) || (t == 0)) {
+	if (canbepipe && (ioctl(fd, FIONREAD, &t) == -1) || (t == 0)) {
 #ifdef FD_ZERO
 #ifdef FD_ZERO
-		for (;;) {
+		for (cnt = 0;; cnt++) {
 			fd_set check;
 			fd_set check;
 			struct timeval tout = {0, 100 * 1000};
 			struct timeval tout = {0, 100 * 1000};
+			int rv;
 
 
 			FD_ZERO(&check);
 			FD_ZERO(&check);
 			FD_SET(fd, &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
 			 * Avoid soft deadlock: do not read if there
 			 * is nothing to read from sockets and pipes.
 			 * 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)
 				if (errno == EINTR || errno == EAGAIN)
 					continue;
 					continue;
+			} else if (rv == 0 && cnt >= 5) {
 				return 0;
 				return 0;
-			}
-			break;
+			} else
+				break;
 		}
 		}
 #endif
 #endif
 		(void)ioctl(fd, FIONREAD, &t);
 		(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)
 	if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes)
 		r = 1;
 		r = 1;
 	else {
 	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)
 			if (swrite(tfd, buf, (size_t)r) != r)
 				break;
 				break;
 	}
 	}
@@ -341,7 +348,7 @@ uncompressgzipped(struct magic_set *ms, const unsigned char *old,
 	}
 	}
 
 
 	n = (size_t)z.total_out;
 	n = (size_t)z.total_out;
-	inflateEnd(&z);
+	(void)inflateEnd(&z);
 	
 	
 	/* let's keep the nul-terminate tradition */
 	/* let's keep the nul-terminate tradition */
 	(*newch)[n] = '\0';
 	(*newch)[n] = '\0';
@@ -389,8 +396,8 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
 			(void)close(2);
 			(void)close(2);
 #endif
 #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
 #ifdef DEBUG
 		(void)fprintf(stderr, "exec `%s' failed (%s)\n",
 		(void)fprintf(stderr, "exec `%s' failed (%s)\n",
 		    compr[method].argv[0], strerror(errno));
 		    compr[method].argv[0], strerror(errno));
@@ -412,7 +419,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
 			switch (fork()) {
 			switch (fork()) {
 			case 0: /* child */
 			case 0: /* child */
 				(void)close(fdout[0]);
 				(void)close(fdout[0]);
-				if (swrite(fdin[1], old, n) != n) {
+				if (swrite(fdin[1], old, n) != (ssize_t)n) {
 #ifdef DEBUG
 #ifdef DEBUG
 					(void)fprintf(stderr,
 					(void)fprintf(stderr,
 					    "Write failed (%s)\n",
 					    "Write failed (%s)\n",
@@ -446,7 +453,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
 			n = 0;
 			n = 0;
 			goto err;
 			goto err;
 		}
 		}
-		if ((r = sread(fdout[0], *newch, HOWMANY)) <= 0) {
+		if ((r = sread(fdout[0], *newch, HOWMANY, 0)) <= 0) {
 #ifdef DEBUG
 #ifdef DEBUG
 			(void)fprintf(stderr, "Read failed (%s)\n",
 			(void)fprintf(stderr, "Read failed (%s)\n",
 			    strerror(errno));
 			    strerror(errno));

+ 35 - 5
src/file.c

@@ -71,7 +71,7 @@
 #include "patchlevel.h"
 #include "patchlevel.h"
 
 
 #ifndef	lint
 #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 */
 #endif	/* lint */
 
 
 
 
@@ -81,7 +81,7 @@ FILE_RCSID("@(#)$Id: file.c,v 1.104 2006/11/25 17:28:54 christos Exp $")
 #define SYMLINKFLAG ""
 #define SYMLINKFLAG ""
 #endif
 #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
 #ifndef MAXPATHLEN
 #define	MAXPATHLEN	512
 #define	MAXPATHLEN	512
@@ -122,7 +122,7 @@ private void load(const char *, int);
 int
 int
 main(int argc, char *argv[])
 main(int argc, char *argv[])
 {
 {
-	int c;
+	int c, i;
 	int action = 0, didsomefiles = 0, errflg = 0;
 	int action = 0, didsomefiles = 0, errflg = 0;
 	int flags = 0;
 	int flags = 0;
 	char *home, *usermagic;
 	char *home, *usermagic;
@@ -138,6 +138,7 @@ main(int argc, char *argv[])
 		{"brief", 0, 0, 'b'},
 		{"brief", 0, 0, 'b'},
 		{"checking-printout", 0, 0, 'c'},
 		{"checking-printout", 0, 0, 'c'},
 		{"debug", 0, 0, 'd'},
 		{"debug", 0, 0, 'd'},
+		{"exclude", 0, 0, 'e' },
 		{"files-from", 1, 0, 'f'},
 		{"files-from", 1, 0, 'f'},
 		{"separator", 1, 0, 'F'},
 		{"separator", 1, 0, 'F'},
 		{"mime", 0, 0, 'i'},
 		{"mime", 0, 0, 'i'},
@@ -161,6 +162,21 @@ main(int argc, char *argv[])
 	};
 	};
 #endif
 #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
 #ifdef LC_CTYPE
 	/* makes islower etc work for other langs */
 	/* makes islower etc work for other langs */
 	(void)setlocale(LC_CTYPE, "");
 	(void)setlocale(LC_CTYPE, "");
@@ -223,6 +239,17 @@ main(int argc, char *argv[])
 		case 'd':
 		case 'd':
 			flags |= MAGIC_DEBUG|MAGIC_CHECK;
 			flags |= MAGIC_DEBUG|MAGIC_CHECK;
 			break;
 			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':
 		case 'f':
 			if(action)
 			if(action)
 				usage();
 				usage();
@@ -331,7 +358,7 @@ main(int argc, char *argv[])
 
 
 private void
 private void
 /*ARGSUSED*/
 /*ARGSUSED*/
-load(const char *m, int flags)
+load(const char *m __unused, int flags)
 {
 {
 	if (magic)
 	if (magic)
 		return;
 		return;
@@ -404,7 +431,7 @@ process(const char *inname, int wid)
 	if (wid > 0 && !bflag) {
 	if (wid > 0 && !bflag) {
 		(void)printf("%s", std_in ? "/dev/stdin" : inname);
 		(void)printf("%s", std_in ? "/dev/stdin" : inname);
 		if (nulsep)
 		if (nulsep)
-			(void)puts('\0');
+			(void)putc('\0', stdout);
 		else
 		else
 			(void)printf("%s", separator);
 			(void)printf("%s", separator);
 		(void)printf("%*s ",
 		(void)printf("%*s ",
@@ -535,6 +562,9 @@ help(void)
 "  -c, --checking-printout    print the parsed form of the magic file, use in\n"
 "  -c, --checking-printout    print the parsed form of the magic file, use in\n"
 "                               conjunction with -m to debug a new magic file\n"
 "                               conjunction with -m to debug a new magic file\n"
 "                               before installing it\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, --files-from FILE      read the filenames to be examined from FILE\n"
 "  -F, --separator string     use string as separator instead of `:'\n"
 "  -F, --separator string     use string as separator instead of `:'\n"
 "  -i, --mime                 output mime type strings\n"
 "  -i, --mime                 output mime type strings\n"

+ 133 - 113
src/file.h

@@ -27,7 +27,7 @@
  */
  */
 /*
 /*
  * file.h - definitions for file(1) program
  * 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__
 #ifndef __file_h__
@@ -46,10 +46,13 @@
 #ifdef HAVE_INTTYPES_H
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
 #include <inttypes.h>
 #endif
 #endif
+#include <regex.h>
 #include <sys/types.h>
 #include <sys/types.h>
 /* Do this here and now, because struct stat gets re-defined on solaris */
 /* Do this here and now, because struct stat gets re-defined on solaris */
 #include <sys/stat.h>
 #include <sys/stat.h>
 
 
+#define ENABLE_CONDITIONALS
+
 #ifndef MAGIC
 #ifndef MAGIC
 #define MAGIC "/etc/magic"
 #define MAGIC "/etc/magic"
 #endif
 #endif
@@ -66,6 +69,28 @@
 #endif
 #endif
 #define public
 #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
 #ifndef HOWMANY
 # define HOWMANY (256 * 1024)	/* how much of the file to look at */
 # define HOWMANY (256 * 1024)	/* how much of the file to look at */
 #endif
 #endif
@@ -74,7 +99,7 @@
 #define MAXstring 32		/* max leng of "string" types */
 #define MAXstring 32		/* max leng of "string" types */
 
 
 #define MAGICNO		0xF11E041C
 #define MAGICNO		0xF11E041C
-#define VERSIONNO	3
+#define VERSIONNO	4
 #define FILE_MAGICSIZE	(32 * 4)
 #define FILE_MAGICSIZE	(32 * 4)
 
 
 #define	FILE_LOAD	0
 #define	FILE_LOAD	0
@@ -86,17 +111,20 @@ struct magic {
 	uint16_t cont_level;	/* level of ">" */
 	uint16_t cont_level;	/* level of ">" */
 	uint8_t nospflag;	/* supress space character */
 	uint8_t nospflag;	/* supress space character */
 	uint8_t flag;
 	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 */
 	/* Word 2 */
 	uint8_t reln;		/* relation (0=eq, '>'=gt, etc) */
 	uint8_t reln;		/* relation (0=eq, '>'=gt, etc) */
 	uint8_t vallen;		/* length of string value, if any */
 	uint8_t vallen;		/* length of string value, if any */
 	uint8_t type;		/* int, short, long or string. */
 	uint8_t type;		/* int, short, long or string. */
 	uint8_t in_type;	/* type of indirrection */
 	uint8_t in_type;	/* type of indirrection */
+#define 			FILE_INVALID	0
 #define 			FILE_BYTE	1
 #define 			FILE_BYTE	1
 #define				FILE_SHORT	2
 #define				FILE_SHORT	2
+#define				FILE_DEFAULT	3
 #define				FILE_LONG	4
 #define				FILE_LONG	4
 #define				FILE_STRING	5
 #define				FILE_STRING	5
 #define				FILE_DATE	6
 #define				FILE_DATE	6
@@ -126,89 +154,33 @@ struct magic {
 #define				FILE_QLDATE	30
 #define				FILE_QLDATE	30
 #define				FILE_LEQLDATE	31
 #define				FILE_LEQLDATE	31
 #define				FILE_BEQLDATE	32
 #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_NONE 0
 #define FILE_FMT_NUM  1 /* "cduxXi" */
 #define FILE_FMT_NUM  1 /* "cduxXi" */
 #define FILE_FMT_STR  2 /* "s" */
 #define FILE_FMT_STR  2 /* "s" */
 #define FILE_FMT_QUAD 3 /* "ll" */
 #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 */
 	/* Word 3 */
 	uint8_t in_op;		/* operator for indirection */
 	uint8_t in_op;		/* operator for indirection */
 	uint8_t mask_op;	/* operator for mask */
 	uint8_t mask_op;	/* operator for mask */
+#ifdef ENABLE_CONDITIONALS
+	uint8_t cond;		/* conditional type */
+	uint8_t dummy1;	
+#else
 	uint8_t dummy1;	
 	uint8_t dummy1;	
 	uint8_t dummy2;	
 	uint8_t dummy2;	
+#endif
+
 #define				FILE_OPS	"&|^+-*/%"
 #define				FILE_OPS	"&|^+-*/%"
 #define				FILE_OPAND	0
 #define				FILE_OPAND	0
 #define				FILE_OPOR	1
 #define				FILE_OPOR	1
@@ -218,8 +190,20 @@ struct magic {
 #define				FILE_OPMULTIPLY	5
 #define				FILE_OPMULTIPLY	5
 #define				FILE_OPDIVIDE	6
 #define				FILE_OPDIVIDE	6
 #define				FILE_OPMODULO	7
 #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_OPINVERSE	0x40
 #define				FILE_OPINDIRECT	0x80
 #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 */
 	/* Word 4 */
 	uint32_t offset;	/* offset to magic number */
 	uint32_t offset;	/* offset to magic number */
 	/* Word 5 */
 	/* Word 5 */
@@ -227,33 +211,44 @@ struct magic {
 	/* Word 6 */
 	/* Word 6 */
 	uint32_t lineno;	/* line number in magic file */
 	uint32_t lineno;	/* line number in magic file */
 	/* Word 7,8 */
 	/* 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 */
 	/* Words 9-16 */
 	union VALUETYPE {
 	union VALUETYPE {
 		uint8_t b;
 		uint8_t b;
 		uint16_t h;
 		uint16_t h;
 		uint32_t l;
 		uint32_t l;
 		uint64_t q;
 		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 hs[2];	/* 2 bytes of a fixed-endian "short" */
 		uint8_t hl[4];	/* 4 bytes of a fixed-endian "long" */
 		uint8_t hl[4];	/* 4 bytes of a fixed-endian "long" */
 		uint8_t hq[8];	/* 8 bytes of a fixed-endian "quad" */
 		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 */
 	} value;		/* either number or string */
 	/* Words 17..31 */
 	/* Words 17..31 */
 	char desc[MAXDESC];	/* description */
 	char desc[MAXDESC];	/* description */
 };
 };
 
 
 #define BIT(A)   (1 << (A))
 #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_BLANK		'B'
 #define CHAR_COMPACT_OPTIONAL_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 */
 /* list of magic entries */
@@ -267,54 +262,79 @@ struct mlist {
 };
 };
 
 
 struct magic_set {
 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;
 struct stat;
 protected const char *file_fmttime(uint32_t, int);
 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_fsmagic(struct magic_set *, const char *, struct stat *);
 protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
 protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
 protected int file_printf(struct magic_set *, const char *, ...);
 protected int file_printf(struct magic_set *, const char *, ...);
 protected int file_reset(struct magic_set *);
 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_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_is_tar(struct magic_set *, const unsigned char *, size_t);
 protected int file_softmagic(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 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_delmagic(struct magic *, int type, size_t entries);
 protected void file_badread(struct magic_set *);
 protected void file_badread(struct magic_set *);
 protected void file_badseek(struct magic_set *);
 protected void file_badseek(struct magic_set *);
 protected void file_oomem(struct magic_set *, size_t);
 protected void file_oomem(struct magic_set *, size_t);
 protected void file_error(struct magic_set *, int, const char *, ...);
 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_magwarn(struct magic_set *, const char *, ...);
 protected void file_mdump(struct magic *);
 protected void file_mdump(struct magic *);
 protected void file_showstr(FILE *, const char *, size_t);
 protected void file_showstr(FILE *, const char *, size_t);
 protected size_t file_mbswidth(const char *);
 protected size_t file_mbswidth(const char *);
 protected const char *file_getbuffer(struct magic_set *);
 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
 #ifndef COMPILE_ONLY
 extern const char *file_names[];
 extern const char *file_names[];

+ 1 - 1
src/fsmagic.c

@@ -57,7 +57,7 @@
 #undef HAVE_MAJOR
 #undef HAVE_MAJOR
 
 
 #ifndef	lint
 #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 */
 #endif	/* lint */
 
 
 protected int
 protected int

+ 99 - 33
src/funcs.c

@@ -26,6 +26,7 @@
  */
  */
 #include "file.h"
 #include "file.h"
 #include "magic.h"
 #include "magic.h"
+#include <assert.h>
 #include <stdarg.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
@@ -38,7 +39,7 @@
 #endif
 #endif
 
 
 #ifndef	lint
 #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 */
 #endif	/* lint */
 
 
 #ifndef HAVE_VSNPRINTF
 #ifndef HAVE_VSNPRINTF
@@ -52,28 +53,32 @@ protected int
 file_printf(struct magic_set *ms, const char *fmt, ...)
 file_printf(struct magic_set *ms, const char *fmt, ...)
 {
 {
 	va_list ap;
 	va_list ap;
-	size_t len;
+	size_t len, size;
 	char *buf;
 	char *buf;
 
 
 	va_start(ap, fmt);
 	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);
 		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;
 			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.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);
 		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);
 	va_end(ap);
+	ms->o.ptr += len;
+	ms->o.left -= len;
 	return 0;
 	return 0;
 }
 }
 
 
@@ -81,18 +86,22 @@ file_printf(struct magic_set *ms, const char *fmt, ...)
  * error - print best error message possible
  * error - print best error message possible
  */
  */
 /*VARARGS*/
 /*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 */
 	/* Only the first error is ok */
 	if (ms->haderr)
 	if (ms->haderr)
 		return;
 		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) {
 	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)",
 		(void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",
 		    strerror(error));
 		    strerror(error));
 	}
 	}
@@ -100,6 +109,28 @@ file_error(struct magic_set *ms, int error, const char *f, ...)
 	ms->error = error;
 	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
 protected void
 file_oomem(struct magic_set *ms, size_t len)
 file_oomem(struct magic_set *ms, size_t len)
@@ -121,17 +152,36 @@ file_badread(struct magic_set *ms)
 
 
 #ifndef COMPILE_ONLY
 #ifndef COMPILE_ONLY
 protected int
 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;
     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 */
     /* 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 */
 	/* 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) */
 	    /* 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 */
 		/* 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 */
 		    /* abandon hope, all ye who remain here */
 		    if (file_printf(ms, ms->flags & MAGIC_MIME ?
 		    if (file_printf(ms, ms->flags & MAGIC_MIME ?
 			(nb ? "application/octet-stream" :
 			(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;
     return m;
 }
 }
 #endif
 #endif
@@ -172,8 +235,8 @@ file_reset(struct magic_set *ms)
 protected const char *
 protected const char *
 file_getbuffer(struct magic_set *ms)
 file_getbuffer(struct magic_set *ms)
 {
 {
-	char *nbuf, *op, *np;
-	size_t nsize;
+	char *pbuf, *op, *np;
+	size_t psize, len;
 
 
 	if (ms->haderr)
 	if (ms->haderr)
 		return NULL;
 		return NULL;
@@ -181,14 +244,17 @@ file_getbuffer(struct magic_set *ms)
 	if (ms->flags & MAGIC_RAW)
 	if (ms->flags & MAGIC_RAW)
 		return ms->o.buf;
 		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;
 			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)
 #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
 #ifndef HAVE_VSNPRINTF
 int
 int

+ 1 - 1
src/is_tar.c

@@ -45,7 +45,7 @@
 #include "tar.h"
 #include "tar.h"
 
 
 #ifndef lint
 #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
 #endif
 
 
 #define	isodigit(c)	( ((c) >= '0') && ((c) <= '7') )
 #define	isodigit(c)	( ((c) >= '0') && ((c) <= '7') )

+ 8 - 33
src/magic.c

@@ -63,7 +63,7 @@
 #include "patchlevel.h"
 #include "patchlevel.h"
 
 
 #ifndef	lint
 #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 */
 #endif	/* lint */
 
 
 #ifdef __EMX__
 #ifdef __EMX__
@@ -94,7 +94,7 @@ magic_open(int flags)
 		goto free1;
 		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)
 	if (ms->o.buf == NULL)
 		goto free1;
 		goto free1;
 
 
@@ -102,11 +102,10 @@ magic_open(int flags)
 	if (ms->o.pbuf == NULL)
 	if (ms->o.pbuf == NULL)
 		goto free2;
 		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;
 		goto free3;
 	
 	
-	ms->o.len = 0;
 	ms->haderr = 0;
 	ms->haderr = 0;
 	ms->error = -1;
 	ms->error = -1;
 	ms->mlist = NULL;
 	ms->mlist = NULL;
@@ -162,7 +161,7 @@ magic_close(struct magic_set *ms)
 	free_mlist(ms->mlist);
 	free_mlist(ms->mlist);
 	free(ms->o.pbuf);
 	free(ms->o.pbuf);
 	free(ms->o.buf);
 	free(ms->o.buf);
-	free(ms->c.off);
+	free(ms->c.li);
 	free(ms);
 	free(ms);
 }
 }
 
 
@@ -305,7 +304,7 @@ magic_file(struct magic_set *ms, const char *inname)
 		ssize_t r = 0;
 		ssize_t r = 0;
 
 
 		while ((r = sread(fd, (void *)&buf[nbytes],
 		while ((r = sread(fd, (void *)&buf[nbytes],
-		    (size_t)(HOWMANY - nbytes))) > 0) {
+		    (size_t)(HOWMANY - nbytes), 1)) > 0) {
 			nbytes += r;
 			nbytes += r;
 			if (r < PIPE_BUF) break;
 			if (r < PIPE_BUF) break;
 		}
 		}
@@ -334,32 +333,8 @@ magic_file(struct magic_set *ms, const char *inname)
 			goto done;
 			goto done;
 	} else {
 	} else {
 		(void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
 		(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;
 			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;
 	rv = 0;
 done:
 done:
@@ -378,7 +353,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
 	 * The main work is done here!
 	 * The main work is done here!
 	 * We have the file name and/or the data buffer to be identified. 
 	 * 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 NULL;
 	}
 	}
 	return file_getbuffer(ms);
 	return file_getbuffer(ms);

+ 20 - 11
src/magic.h

@@ -29,17 +29,26 @@
 
 
 #include <sys/types.h>
 #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
 #ifdef __cplusplus
 extern "C" {
 extern "C" {

+ 1 - 1
src/names.h

@@ -32,7 +32,7 @@
  * appear at fixed offsets into the file. Don't make HOWMANY
  * appear at fixed offsets into the file. Don't make HOWMANY
  * too high unless you have a very fast CPU.
  * 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	FILE_VERSION_MAJOR	4
-#define	patchlevel		19
+#define	patchlevel		20
 
 
 /*
 /*
  * Patchlevel file for Ian Darwin's MAGIC command.
  * 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 $
  * $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
  * Revision 1.62  2006/12/11 21:49:58  christos
  * time for 4.19
  * time for 4.19
  *
  *

+ 33 - 19
src/print.c

@@ -41,7 +41,7 @@
 #include <time.h>
 #include <time.h>
 
 
 #ifndef lint
 #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 */
 #endif  /* lint */
 
 
 #define SZOF(a)	(sizeof(a) / sizeof(a[0]))
 #define SZOF(a)	(sizeof(a) / sizeof(a[0]))
@@ -64,8 +64,8 @@ file_mdump(struct magic *m)
 		if (m->in_op & FILE_OPINVERSE)
 		if (m->in_op & FILE_OPINVERSE)
 			(void) fputc('~', stderr);
 			(void) fputc('~', stderr);
 		(void) fprintf(stderr, "%c%d),",
 		(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);
 				m->in_offset);
 	}
 	}
 	(void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
 	(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*");
 		       (m->type < file_nnames) ? file_names[m->type] : "*bad*");
 	if (m->mask_op & FILE_OPINVERSE)
 	if (m->mask_op & FILE_OPINVERSE)
 		(void) fputc('~', stderr);
 		(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);
 				(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,
 				(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);
 	(void) fprintf(stderr, ",%c", m->reln);
 
 
 	if (m->reln != 'x') {
 	if (m->reln != 'x') {
@@ -146,6 +157,9 @@ file_mdump(struct magic *m)
 			(void)fprintf(stderr, "%s,",
 			(void)fprintf(stderr, "%s,",
 			    file_fmttime((uint32_t)m->value.q, 0));
 			    file_fmttime((uint32_t)m->value.q, 0));
 			break;
 			break;
+		case FILE_DEFAULT:
+			/* XXX - do anything here? */
+			break;
 		default:
 		default:
 			(void) fputs("*bad*", stderr);
 			(void) fputs("*bad*", stderr);
 			break;
 			break;
@@ -169,7 +183,7 @@ file_magwarn(struct magic_set *ms, const char *f, ...)
 	    (unsigned long)ms->line);
 	    (unsigned long)ms->line);
 	(void) vfprintf(stderr, f, va);
 	(void) vfprintf(stderr, f, va);
 	va_end(va);
 	va_end(va);
-	fputc('\n', stderr);
+	(void) fputc('\n', stderr);
 }
 }
 
 
 protected const char *
 protected const char *

+ 4 - 4
src/readelf.c

@@ -37,7 +37,7 @@
 #include "readelf.h"
 #include "readelf.h"
 
 
 #ifndef lint
 #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
 #endif
 
 
 #ifdef	ELFCORE
 #ifdef	ELFCORE
@@ -155,7 +155,7 @@ getu64(int swap, uint64_t value)
 #define xph_type	(class == ELFCLASS32		\
 #define xph_type	(class == ELFCLASS32		\
 			 ? getu32(swap, ph32.p_type)	\
 			 ? getu32(swap, ph32.p_type)	\
 			 : getu32(swap, ph64.p_type))
 			 : getu32(swap, ph64.p_type))
-#define xph_offset	(class == ELFCLASS32		\
+#define xph_offset	(off_t)(class == ELFCLASS32	\
 			 ? getu32(swap, ph32.p_offset)	\
 			 ? getu32(swap, ph32.p_offset)	\
 			 : getu64(swap, ph64.p_offset))
 			 : getu64(swap, ph64.p_offset))
 #define xph_align	(size_t)((class == ELFCLASS32	\
 #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
 		 * This is a PT_NOTE section; loop through all the notes
 		 * in the section.
 		 * 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);
 			file_badseek(ms);
 			return -1;
 			return -1;
 		}
 		}
@@ -858,7 +858,7 @@ dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off,
 			 * This is a PT_NOTE section; loop through all the notes
 			 * This is a PT_NOTE section; loop through all the notes
 			 * in the section.
 			 * in the section.
 			 */
 			 */
-			if (lseek(fd, (off_t)xph_offset, SEEK_SET)
+			if (lseek(fd, xph_offset, SEEK_SET)
 			    == (off_t)-1) {
 			    == (off_t)-1) {
 				file_badseek(ms);
 				file_badseek(ms);
 				return -1;
 				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.
  * 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_BADARCH	3		/* bad archive */
 #define	EX_SYSTEM	4		/* system gave unexpected error */
 #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.
  * Structure for keeping track of filenames and lists thereof.
  */
  */
@@ -162,12 +116,6 @@ struct name {
 	char		name[NAMSIZ+1];
 	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
  * Due to the next struct declaration, each routine that includes
@@ -185,21 +133,3 @@ struct link {
 	short		linkcount;
 	short		linkcount;
 	char		name[NAMSIZ+1];
 	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);
     ms = magic_open(MAGIC_NONE);
     if (ms == NULL) {
     if (ms == NULL) {
-	printf("ERROR: out of memory\n");
+	(void) printf("ERROR: out of memory\n");
 	return 1;
 	return 1;
     }
     }
     if (magic_load(ms, NULL) == -1) {
     if (magic_load(ms, NULL) == -1) {
-	printf("ERROR: %s\n", magic_error(ms));
+	(void) printf("ERROR: %s\n", magic_error(ms));
 	return 1;
 	return 1;
     }
     }
 
 
     for (i = 1; i < argc; i++) {
     for (i = 1; i < argc; i++) {
 	if ((m = magic_file(ms, argv[i])) == NULL)
 	if ((m = magic_file(ms, argv[i])) == NULL)
-	    printf("ERROR: %s\n", magic_error(ms));
+	    (void) printf("ERROR: %s\n", magic_error(ms));
 	else
 	else
-	    printf("%s: %s\n", argv[i], m);
+	    (void) printf("%s: %s\n", argv[i], m);
     }
     }
 
 
     magic_close(ms);
     magic_close(ms);