Browse Source

Import upstream version 5.01

Christos Zoulas 15 years ago
parent
commit
e801c4a8c3
44 changed files with 5211 additions and 4381 deletions
  1. 46 0
      ChangeLog
  2. 2 0
      Makefile.am
  3. 6 1
      Makefile.in
  4. 5 2
      README
  5. 11 0
      acinclude.m4
  6. 1023 535
      aclocal.m4
  7. 3 0
      config.h.in
  8. 2941 3308
      configure
  9. 7 3
      configure.ac
  10. 4 1
      doc/Makefile.in
  11. 733 277
      ltmain.sh
  12. 9 0
      magic/Magdir/cafebabe
  13. 9 0
      magic/Magdir/compress
  14. 25 0
      magic/Magdir/database
  15. 3 3
      magic/Magdir/erlang
  16. 1 1
      magic/Magdir/filesystems
  17. 4 2
      magic/Magdir/fonts
  18. 1 1
      magic/Magdir/fortran
  19. 32 0
      magic/Magdir/kml
  20. 1 1
      magic/Magdir/linux
  21. 9 9
      magic/Magdir/lisp
  22. 4 0
      magic/Magdir/troff
  23. 6 0
      magic/Magdir/windows
  24. 2 1
      magic/Makefile.am
  25. 6 2
      magic/Makefile.in
  26. 4 1
      python/Makefile.in
  27. 4 1
      src/Makefile.in
  28. 38 28
      src/apprentice.c
  29. 2 2
      src/apptype.c
  30. 142 101
      src/cdf.c
  31. 24 17
      src/cdf.h
  32. 3 2
      src/cdf_time.c
  33. 4 1
      src/compress.c
  34. 2 2
      src/file.c
  35. 8 2
      src/file.h
  36. 9 2
      src/funcs.c
  37. 2 2
      src/getopt_long.c
  38. 4 30
      src/magic.c
  39. 5 2
      src/patchlevel.h
  40. 48 29
      src/readcdf.c
  41. 13 11
      src/softmagic.c
  42. 1 0
      src/strlcat.c
  43. 1 0
      src/strlcpy.c
  44. 4 1
      tests/Makefile.in

+ 46 - 0
ChangeLog

@@ -1,3 +1,49 @@
+2009-04-30  17:10  Christos Zoulas <christos@zoulas.com>
+
+	* Fix more cdf lossage. All the documents I have
+	  right now print the correct information.
+
+2009-03-27  18:43  Christos Zoulas <christos@zoulas.com>
+
+	* don't print \012- separators in the same magic entry 
+	  if it consists of multiple magic printing lines.
+
+2009-03-23  10:20  Christos Zoulas <christos@zoulas.com>
+
+	* Avoid file descriptor leak in compress code from
+	  (Daniel Novotny)
+
+2009-03-18  16:50  Christos Zoulas <christos@zoulas.com>
+
+	* Allow escaping of relation characters, so that we can say \^[A-Z]
+	  and the ^ is not eaten as a relation char.
+
+	* Fix troff and fortran to their previous glory using
+	  regex. This was broken since their removel from ascmagic.
+
+2009-03-10  16:50  Christos Zoulas <christos@zoulas.com>
+
+	* don't use strlen in strndup() (Toby Peterson)
+
+2009-03-10  7:45  Christos Zoulas <christos@zoulas.com>
+
+	* avoid c99 syntax.
+
+2009-02-23 15:45  Christos Zoulas <christos@zoulas.com>
+
+	* make the cdf code use the buffer first if available,
+	  and then the fd code.
+
+2009-02-13 13:45  Christos Zoulas <christos@zoulas.com>
+
+	* look for struct option to determine if getopt.h is usable for IRIX.
+
+	* sanitize cdf document strings
+
+2009-02-04 13:25  Christos Zoulas <christos@zoulas.com>
+
+	* fix OS/2 warnings.
+
 2008-12-12 15:50  Christos Zoulas <christos@zoulas.com>
 
 	* fix initial offset calculation for non 4K sector files

+ 2 - 0
Makefile.am

@@ -1,3 +1,5 @@
+#ACLOCAL_AMFLAGS = -I m4
+
 EXTRA_DIST = MAINT
 
 SUBDIRS = src magic tests doc python

+ 6 - 1
Makefile.in

@@ -13,8 +13,9 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#ACLOCAL_AMFLAGS = -I m4
 VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@@ -72,6 +73,7 @@ DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 distuninstallcheck_listfiles = find . -type f -print
 distcleancheck_listfiles = find . -type f -print
+pkgdatadir = @pkgdatadir@
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
@@ -91,6 +93,7 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
 ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
@@ -113,6 +116,7 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -122,6 +126,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@

+ 5 - 2
README

@@ -1,15 +1,18 @@
 ** README for file(1) Command **
-@(#) $File: README,v 1.41 2008/12/02 16:34:46 christos Exp $
+@(#) $File: README,v 1.42 2009/02/14 15:16:24 christos Exp $
 
 E-mail: christos@astron.com
 Mailing List: file@mx.gw.com
 
 Phone: Do not even think of telephoning me about this program. Send cash first!
 
-This is Release 4.x of Ian Darwin's (copyright but distributable)
+This is Release 5.x of Ian Darwin's (copyright but distributable)
 file(1) command. This version is the standard "file" command for Linux,
 *BSD, and other systems. (See "patchlevel.h" for the exact release number).
 
+The major changes for 5.x are CDF file parsing, indirect magic, and
+overhaul in mime and ascii encoding handling.
+
 The major feature of 4.x is the refactoring of the code into a library,
 and the re-write of the file command in terms of that library. The library
 itself, libmagic can be used by 3rd party programs that wish to identify

+ 11 - 0
acinclude.m4

@@ -9,6 +9,7 @@ AC_CACHE_CHECK([for tm_zone in struct tm], ac_cv_struct_tm_zone,
 if test "$ac_cv_struct_tm_zone" = yes; then
   AC_DEFINE(HAVE_TM_ZONE,1,[HAVE_TM_ZONE])
 fi
+
 AC_CACHE_CHECK(for tzname, ac_cv_var_tzname,
 [AC_TRY_LINK(
 changequote(<<, >>)dnl
@@ -29,6 +30,7 @@ AC_CACHE_CHECK([for tm_isdst in struct tm], ac_cv_struct_tm_isdst,
 if test "$ac_cv_struct_tm_isdst" = yes; then
   AC_DEFINE(HAVE_TM_ISDST,1,[HAVE_TM_ISDST])
 fi
+
 AC_CACHE_CHECK(for daylight, ac_cv_var_daylight,
 [AC_TRY_LINK(
 changequote(<<, >>)dnl
@@ -42,3 +44,12 @@ changequote([, ])dnl
     AC_DEFINE(HAVE_DAYLIGHT,1,[HAVE_DAYLIGHT])
   fi
 ])
+
+AC_DEFUN([AC_STRUCT_OPTION_GETOPT_H],
+[AC_CACHE_CHECK([for struct option in getopt], ac_cv_struct_option_getopt_h,
+[AC_TRY_COMPILE([#include <getopt.h>], [struct option op; op.name;],
+  ac_cv_struct_option_getopt_h=yes, ac_cv_struct_option_getopt_h=no)])
+if test "$ac_cv_struct_option_getopt_h" = yes; then
+  AC_DEFINE(HAVE_STRUCT_OPTION,1,[HAVE_STRUCT_OPTION])
+fi
+])

File diff suppressed because it is too large
+ 1023 - 535
aclocal.m4


+ 3 - 0
config.h.in

@@ -93,6 +93,9 @@
 /* Define to 1 if you have the `strtoul' function. */
 #undef HAVE_STRTOUL
 
+/* HAVE_STRUCT_OPTION */
+#undef HAVE_STRUCT_OPTION
+
 /* Define to 1 if `st_rdev' is member of `struct stat'. */
 #undef HAVE_STRUCT_STAT_ST_RDEV
 

File diff suppressed because it is too large
+ 2941 - 3308
configure


+ 7 - 3
configure.ac

@@ -1,7 +1,8 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT(file, 5.00, christos@astron.com)
+AC_INIT(file, 5.01, christos@astron.com)
 AM_INIT_AUTOMAKE
 AM_CONFIG_HEADER(config.h)
+#AC_CONFIG_MACRO_DIR([m4])
 
 AC_MSG_CHECKING(for builtin ELF support)
 AC_ARG_ENABLE(elf,
@@ -46,6 +47,7 @@ fi], [
   fsect=4
 ])
 
+AC_SUBST([pkgdatadir], ['$(datadir)/misc'])
 AC_SUBST(fsect)
 AM_CONDITIONAL(FSECT5, test x$fsect = x5)
 
@@ -82,6 +84,8 @@ AC_SYS_LARGEFILE
 AC_FUNC_FSEEKO
 AC_TYPE_MBSTATE_T
 
+AC_STRUCT_OPTION_GETOPT_H
+
 AC_CHECK_TYPES([uint8_t, uint16_t, uint32_t, int32_t, uint64_t, int64_t])
 AC_CHECK_SIZEOF(long long)
 AH_BOTTOM([
@@ -116,7 +120,7 @@ typedef long int64_t;
 AC_MSG_CHECKING(for gcc compiler warnings)
 AC_ARG_ENABLE(warnings,
 [  --disable-warnings	disable compiler warnings],
-[if test "${enableval}" = no -o $GCC = no; then
+[if test "${enableval}" = no -o "$GCC" = no; then
    AC_MSG_RESULT(no)
    WARNINGS=
 else
@@ -126,7 +130,7 @@ else
        -Wsign-compare -Wreturn-type -Wswitch -Wshadow \
        -Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter"
 fi], [
-if test $GCC = no; then
+if test "$GCC" = no; then
    WARNINGS=
    AC_MSG_RESULT(no)
 else

+ 4 - 1
doc/Makefile.in

@@ -14,7 +14,6 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@@ -52,6 +51,7 @@ man5dir = $(mandir)/man5
 NROFF = nroff
 MANS = $(man_MANS)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
@@ -71,6 +71,7 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
 ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
@@ -93,6 +94,7 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -102,6 +104,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@

File diff suppressed because it is too large
+ 733 - 277
ltmain.sh


+ 9 - 0
magic/Magdir/cafebabe

@@ -17,6 +17,15 @@
 >4	belong		>30		compiled Java class data,
 >>6	beshort		x	        version %d.
 >>4	beshort		x       	\b%d
+# Which is which?
+#>>4	belong		0x032d		(Java 1.0)
+#>>4	belong		0x032d		(Java 1.1)
+>>4	belong		0x002e		(Java 1.2)
+>>4	belong		0x002f		(Java 1.3)
+>>4	belong		0x0030		(Java 1.4)
+>>4	belong		0x0031		(Java 1.5)
+>>4	belong		0x0032		(Java 1.6)
+
 
 0	belong		0xcafebabe
 >4	belong		1		Mach-O fat file with 1 architecture

+ 9 - 0
magic/Magdir/compress

@@ -195,6 +195,10 @@
 # bug #364260)
 #0	string		]\000\000\200\000	LZMA compressed data
 
+# http://tukaani.org/xz/xz-file-format.txt
+0	ustring		\xFD7zXZ\x00		xz compressed data
+!:mime	application/x-xz
+
 # AFX compressed files (Wolfram Kleff)
 2	string		-afx-		AFX compressed file data
 
@@ -208,3 +212,8 @@
 >4	byte		x		- version %d
 >5	byte		x		\b.%d
 >6	belong		x		(%d bytes)
+
+# Type: XZ
+# URL: http://tukaani.org/xz/
+0	string		\xfd\x37\x7a\x58\x5a\x00	XZ compressed data
+!:mime application/x-xz

+ 25 - 0
magic/Magdir/database

@@ -242,3 +242,28 @@
 # URL:  http://www.grc.nasa.gov/WWW/cgns/adf/
 # From: Nicolas Chauvat <nicolas.chauvat@logilab.fr>
 0	string	@(#)ADF\ Database	CGNS Advanced Data Format
+
+# Tokyo Cabinet magic data
+# http://tokyocabinet.sourceforge.net/index.html
+0	string		ToKyO\ CaBiNeT\n	Tokyo Cabinet
+>14	string		x			\b (%s)
+>32	byte		0			\b, Hash
+!:mime	application/x-tokyocabinet-hash
+>32	byte		1			\b, B+ tree
+!:mime	application/x-tokyocabinet-btree
+>32	byte		2			\b, Fixed-length
+!:mime	application/x-tokyocabinet-fixed
+>32	byte		3			\b, Table
+!:mime	application/x-tokyocabinet-table
+>33	byte		&1			\b, [open]
+>33	byte		&2			\b, [fatal]
+>34	byte		x			\b, apow=%d
+>35	byte		x			\b, fpow=%d
+>36	byte		&0x01			\b, [large]
+>36	byte		&0x02			\b, [deflate]
+>36	byte		&0x04			\b, [bzip]
+>36	byte		&0x08			\b, [tcbs]
+>36	byte		&0x10			\b, [excodec]
+>40	lequad		x			\b, bnum=%lld
+>48	lequad		x			\b, rnum=%lld
+>56	lequad		x			\b, fsiz=%lld

+ 3 - 3
magic/Magdir/erlang

@@ -12,7 +12,7 @@
 >8	string	BEAM		Erlang BEAM file
 
 # 4.2 version may have a copyright notice!
-4	string	Tue Jan 22 14:32:44 MET 1991	Erlang JAM file - version 4.2
-79	string	Tue Jan 22 14:32:44 MET 1991	Erlang JAM file - version 4.2
+4	string	Tue\ Jan\ 22\ 14:32:44\ MET\ 1991	Erlang JAM file - version 4.2
+79	string	Tue\ Jan\ 22\ 14:32:44\ MET\ 1991	Erlang JAM file - version 4.2
 
-4	string	1.0 Fri Feb 3 09:55:56 MET 1995	Erlang JAM file - version 4.3
+4	string	1.0\ Fri\ Feb\ 3\ 09:55:56\ MET\ 1995	Erlang JAM file - version 4.3

+ 1 - 1
magic/Magdir/filesystems

@@ -891,7 +891,7 @@
 0x410	leshort		0x2478		Minix filesystem, version 2, 30 char names
 
 # romfs filesystems - Juan Cespedes <cespedes@debian.org>
-0	string		-rom1fs-\0	romfs filesystem, version 1
+0	string		-rom1fs-	romfs filesystem, version 1
 >8	belong	x			%d bytes,
 >16	string	x			named %s.
 

+ 4 - 2
magic/Magdir/fonts

@@ -6,8 +6,8 @@
 0	short		017001		byte-swapped Berkeley vfont data
 
 # PostScript fonts (must precede "printer" entries), quinlan@yggdrasil.com
-0	search/1	%!PS-AdobeFont-1.	PostScript Type 1 font text
->20	search/1	>\0			(%s)
+0	string		%!PS-AdobeFont-1.	PostScript Type 1 font text
+>20	string		>\0			(%s)
 6	string		%!PS-AdobeFont-1.	PostScript Type 1 font program data
 
 # X11 font files in SNF (Server Natural Format) format
@@ -55,6 +55,8 @@
 0	string		\007\001\001\000Copyright\ (c)\ 199	Adobe Multiple Master font
 0	string		\012\001\001\000Copyright\ (c)\ 199	Adobe Multiple Master font
 
+0	string		ttcf		TrueType font collection data
+
 # Opentype font data from Avi Bercovich
 0	string		OTTO		OpenType font data 
 

+ 1 - 1
magic/Magdir/fortran

@@ -1,3 +1,3 @@
 # FORTRAN source
-0	string/c	c\ 		FORTRAN program
+0	regex/100	\^[Cc][\ \t]	FORTRAN program
 !:mime	text/x-fortran

+ 32 - 0
magic/Magdir/kml

@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------
+# Type: Google KML, formerly Keyhole Markup Language
+# Future development of this format has been handed
+# over to the Open Geospatial Consortium.
+# http://www.opengeospatial.org/standards/kml/
+# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
+0 string    \<?xml
+>20  search/400 \ xmlns= 
+>>&0 regex ['"]http://earth.google.com/kml Google KML document
+!:mime application/vnd.google-earth.kml+xml
+>>>&1 string 2.0' \b, version 2.0
+>>>&1 string 2.1' \b, version 2.1
+>>>&1 string 2.2' \b, version 2.2
+
+#------------------------------------------------------------------------------
+# Type: OpenGIS KML, formerly Keyhole Markup Language
+# This standard is maintained by the
+# Open Geospatial Consortium.
+# http://www.opengeospatial.org/standards/kml/
+# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
+>>&0 regex ['"]http://www.opengis.net/kml OpenGIS KML document
+!:mime application/vnd.google-earth.kml+xml
+>>>&1 string 2.2 \b, version 2.2
+
+#------------------------------------------------------------------------------
+# Type: Google KML Archive (ZIP based) 
+# http://code.google.com/apis/kml/documentation/kml_tut.html
+# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
+0 string    PK\003\004
+>4  byte    0x14
+>>30  string doc.kml Compressed Google KML Document, including resources.
+!:mime application/vnd.google-earth.kmz

+ 1 - 1
magic/Magdir/linux

@@ -84,7 +84,7 @@
 514	string		HdrS		Linux kernel
 >510	leshort		0xAA55		x86 boot executable
 >>518	leshort		>0x1ff
->>529	byte		0		zImage,
+>>>529	byte		0		zImage,
 >>>529	byte		1		bzImage,
 >>>(526.s+0x200) string	>\0		version %s,
 >>498	leshort		1		RO-rootFS,

+ 9 - 9
magic/Magdir/lisp

@@ -8,22 +8,22 @@
 #0	string	;;			
 # windows INF files often begin with semicolon and use CRLF as line end
 # lisp files are mainly created on unix system with LF as line end
-#>2	search/2048	!\r		Lisp/Scheme program text
-#>2	search/2048	\r		Windows INF file
+#>2	search/4096	!\r		Lisp/Scheme program text
+#>2	search/4096	\r		Windows INF file
 
-0	search/256	(if\ 			Lisp/Scheme program text
+0	search/4096	(if\ 			Lisp/Scheme program text
 !:mime	text/x-lisp
-0	search/256	(setq\ 			Lisp/Scheme program text
+0	search/4096	(setq\ 			Lisp/Scheme program text
 !:mime	text/x-lisp
-0	search/256	(defvar\ 		Lisp/Scheme program text
+0	search/4096	(defvar\ 		Lisp/Scheme program text
 !:mime	text/x-lisp
-0	search/256	(defparam\ 		Lisp/Scheme program text
+0	search/4096	(defparam\ 		Lisp/Scheme program text
 !:mime	text/x-lisp
-0	search/256	(defun\  		Lisp/Scheme program text
+0	search/4096	(defun\  		Lisp/Scheme program text
 !:mime	text/x-lisp
-0	search/256	(autoload\ 		Lisp/Scheme program text
+0	search/4096	(autoload\ 		Lisp/Scheme program text
 !:mime	text/x-lisp
-0	search/256	(custom-set-variables\ 	Lisp/Scheme program text
+0	search/4096	(custom-set-variables\ 	Lisp/Scheme program text
 !:mime	text/x-lisp
 
 # Emacs 18 - this is always correct, but not very magical.

+ 4 - 0
magic/Magdir/troff

@@ -14,6 +14,10 @@
 !:mime	text/troff
 0	search/1	'''		troff or preprocessor input text
 !:mime	text/troff
+0	regex/20	\^\\.[A-Za-z0-9][A-Za-z0-9][\ \t]	troff or preprocessor input text
+!:mime	text/troff
+0	regex/20	\^\\.[A-Za-z0-9][A-Za-z0-9]$	troff or preprocessor input text
+!:mime	text/troff
 
 # ditroff intermediate output text
 0	search/1	x\ T		ditroff output text

+ 6 - 0
magic/Magdir/windows

@@ -113,3 +113,9 @@
 0	string		REGEDIT4\r\n\r\n	Windows Registry text (Win95 or above)
 0	string		Windows\ Registry\ Editor\ 
 >&0	string		Version\ 5.00\r\n\r\n	Windows Registry text (Win2K or above)
+
+
+# From: Pal Tamas <folti@balabit.hu>
+# Autorun File
+0       string/c          [autorun]\r\n   Microsoft Windows Autorun file.
+!:mime	application/x-setupscript. 

+ 2 - 1
magic/Makefile.am

@@ -1,5 +1,5 @@
 #
-# $File: Makefile.am,v 1.44 2009/01/28 02:11:20 christos Exp $
+# $File: Makefile.am,v 1.45 2009/03/05 22:40:59 christos Exp $
 #
 MAGIC_FRAGMENT_BASE = Magdir
 MAGIC_FRAGMENT_DIR = $(top_srcdir)/magic/$(MAGIC_FRAGMENT_BASE)
@@ -97,6 +97,7 @@ $(MAGIC_FRAGMENT_DIR)/java \
 $(MAGIC_FRAGMENT_DIR)/jpeg \
 $(MAGIC_FRAGMENT_DIR)/karma \
 $(MAGIC_FRAGMENT_DIR)/kde \
+$(MAGIC_FRAGMENT_DIR)/kml \
 $(MAGIC_FRAGMENT_DIR)/lecter \
 $(MAGIC_FRAGMENT_DIR)/lex \
 $(MAGIC_FRAGMENT_DIR)/lif \

+ 6 - 2
magic/Makefile.in

@@ -15,7 +15,6 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@@ -54,6 +53,7 @@ am__installdirs = "$(DESTDIR)$(pkgdatadir)"
 pkgdataDATA_INSTALL = $(INSTALL_DATA)
 DATA = $(pkgdata_DATA)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
@@ -73,6 +73,7 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
 ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
@@ -95,6 +96,7 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -104,6 +106,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
@@ -163,7 +166,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 
 #
-# $File: Makefile.am,v 1.44 2009/01/28 02:11:20 christos Exp $
+# $File: Makefile.am,v 1.45 2009/03/05 22:40:59 christos Exp $
 #
 MAGIC_FRAGMENT_BASE = Magdir
 MAGIC_FRAGMENT_DIR = $(top_srcdir)/magic/$(MAGIC_FRAGMENT_BASE)
@@ -259,6 +262,7 @@ $(MAGIC_FRAGMENT_DIR)/java \
 $(MAGIC_FRAGMENT_DIR)/jpeg \
 $(MAGIC_FRAGMENT_DIR)/karma \
 $(MAGIC_FRAGMENT_DIR)/kde \
+$(MAGIC_FRAGMENT_DIR)/kml \
 $(MAGIC_FRAGMENT_DIR)/lecter \
 $(MAGIC_FRAGMENT_DIR)/lex \
 $(MAGIC_FRAGMENT_DIR)/lif \

+ 4 - 1
python/Makefile.in

@@ -14,7 +14,6 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@@ -44,6 +43,7 @@ CONFIG_CLEAN_FILES =
 SOURCES =
 DIST_SOURCES =
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
@@ -63,6 +63,7 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
 ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
@@ -85,6 +86,7 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -94,6 +96,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@

+ 4 - 1
src/Makefile.in

@@ -17,7 +17,6 @@
 
 
 VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@@ -90,6 +89,7 @@ HEADERS = $(include_HEADERS)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
@@ -109,6 +109,7 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
 ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
@@ -131,6 +132,7 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -140,6 +142,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@

+ 38 - 28
src/apprentice.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.147 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.151 2009/03/18 15:19:23 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -89,8 +89,8 @@ const size_t file_nnames = FILE_NAMES_SIZE;
 
 private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
 private int hextoint(int);
-private const char *getstr(struct magic_set *, const char *, char *, int,
-    int *, int);
+private const char *getstr(struct magic_set *, struct magic *, const char *,
+    int);
 private int parse(struct magic_set *, struct magic_entry **, uint32_t *,
     const char *, size_t, int);
 private void eatsize(const char **);
@@ -324,11 +324,15 @@ file_delmagic(struct magic *p, int type, size_t entries)
 	if (p == NULL)
 		return;
 	switch (type) {
-#ifdef QUICK
 	case 2:
+#ifdef QUICK
 		p--;
 		(void)munmap((void *)p, sizeof(*p) * (entries + 1));
 		break;
+#else
+		(void)&entries;
+		abort();
+		/*NOTREACHED*/
 #endif
 	case 1:
 		p--;
@@ -1712,8 +1716,7 @@ check_format(struct magic_set *ms, struct magic *m)
 		 * string is not one character long
 		 */
 		file_magwarn(ms, "Printf format `%c' is not valid for type "
-		    "`%s' in description `%s'",
-		    ptr && *ptr ? *ptr : '?',
+		    "`%s' in description `%s'", *ptr ? *ptr : '?',
 		    file_names[m->type], m->desc);
 		return -1;
 	}
@@ -1738,8 +1741,6 @@ check_format(struct magic_set *ms, struct magic *m)
 private int
 getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
 {
-	int slen;
-
 	switch (m->type) {
 	case FILE_BESTRING16:
 	case FILE_LESTRING16:
@@ -1747,16 +1748,13 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
 	case FILE_PSTRING:
 	case FILE_REGEX:
 	case FILE_SEARCH:
-		*p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen, action);
+		*p = getstr(ms, m, *p, action == FILE_COMPILE);
 		if (*p == NULL) {
 			if (ms->flags & MAGIC_CHECK)
 				file_magwarn(ms, "cannot get string from `%s'",
 				    m->value.s);
 			return -1;
 		}
-		m->vallen = slen;
-		if (m->type == FILE_PSTRING)
-			m->vallen++;
 		return 0;
 	case FILE_FLOAT:
 	case FILE_BEFLOAT:
@@ -1795,13 +1793,15 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
 /*
  * Convert a string containing C character escapes.  Stop at an unescaped
  * space or tab.
- * Copy the converted version to "p", returning its length in *slen.
- * Return updated scan pointer as function result.
+ * Copy the converted version to "m->value.s", and the length in m->vallen.
+ * Return updated scan pointer as function result. Warn if set.
  */
 private const char *
-getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int action)
+getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
 {
 	const char *origs = s;
+	char	*p = m->value.s;
+	size_t  plen = sizeof(m->value.s);
 	char 	*origp = p;
 	char	*pmax = p + plen - 1;
 	int	c;
@@ -1818,25 +1818,33 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int ac
 			switch(c = *s++) {
 
 			case '\0':
-				if (action == FILE_COMPILE)
+				if (warn)
 					file_magwarn(ms, "incomplete escape");
 				goto out;
 
 			case '\t':
-				if (action == FILE_COMPILE) {
+				if (warn) {
 					file_magwarn(ms,
 					    "escaped tab found, use \\t instead");
-					action++;
+					warn = 0;	/* already did */
 				}
 				/*FALLTHROUGH*/
 			default:
-				if (action == FILE_COMPILE) {
-					if (isprint((unsigned char)c))
-					    file_magwarn(ms,
-						"no need to escape `%c'", c);
-					else
-					    file_magwarn(ms,
-						"unknown escape sequence: \\%03o", c);
+				if (warn) {
+					if (isprint((unsigned char)c)) {
+						/* Allow escaping of 
+						 * ``relations'' */
+						if (strchr("<>&^=!", c)
+						    == NULL) {
+							file_magwarn(ms, "no "
+							    "need to escape "
+							    "`%c'", c);
+						}
+					} else {
+						file_magwarn(ms,
+						    "unknown escape sequence: "
+						    "\\%03o", c);
+					}
 				}
 				/*FALLTHROUGH*/
 			/* space, perhaps force people to use \040? */
@@ -1935,7 +1943,9 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int ac
 	}
 out:
 	*p = '\0';
-	*slen = p - origp;
+	m->vallen = p - origp;
+	if (m->type == FILE_PSTRING)
+		m->vallen++;
 	return s;
 }
 
@@ -2084,7 +2094,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
 		file_oomem(ms, (size_t)st.st_size);
 		goto error1;
 	}
-	if (read(fd, mm, (size_t)st.st_size) != (size_t)st.st_size) {
+	if (read(fd, mm, (size_t)st.st_size) != (ssize_t)st.st_size) {
 		file_badread(ms);
 		goto error1;
 	}
@@ -2107,7 +2117,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
 	else
 		version = ptr[1];
 	if (version != VERSIONNO) {
-		file_error(ms, 0, "File %d.%d supports only %d version magic "
+		file_error(ms, 0, "File %d.%d supports only version %d magic "
 		    "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
 		    VERSIONNO, dbname, version);
 		goto error1;

+ 2 - 2
src/apptype.c

@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: apptype.c,v 1.10 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: apptype.c,v 1.11 2009/02/04 18:24:32 christos Exp $")
 #endif /* lint */
 
 #include <stdlib.h>
@@ -76,7 +76,7 @@ file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
 		}
 		(void)fclose(fp);
 	}
-	rc = DosQueryAppType(path, &type);
+	rc = DosQueryAppType((unsigned char *)path, &type);
 
 	if (fn == NULL) {
 		unlink(path);

+ 142 - 101
src/cdf.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.17 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.22 2009/04/30 21:03:26 christos Exp $")
 #endif
 
 #include <assert.h>
@@ -56,7 +56,7 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.17 2009/02/03 20:27:51 christos Exp $")
 #endif
 
 #ifdef CDF_DEBUG
-#define DPRINTF(a) printf a
+#define DPRINTF(a) printf a, fflush(stdout)
 #else
 #define DPRINTF(a)
 #endif
@@ -227,19 +227,47 @@ cdf_unpack_dir(cdf_directory_t *d, char *buf)
 	CDF_UNPACK(d->d_unused0);
 }
 
+static ssize_t
+cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
+{
+	size_t siz = (size_t)off + len;
+
+	if ((off_t)(off + len) != (off_t)siz) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (info->i_buf != NULL && info->i_len >= siz) {
+		(void)memcpy(buf, &info->i_buf[off], len);
+		return (ssize_t)len;
+	}
+
+	if (info->i_fd == -1)
+		return -1;
+
+	if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1)
+		return -1;
+
+	if (read(info->i_fd, buf, len) != (ssize_t)len)
+		return -1;
+
+	return (ssize_t)len;
+}
+
 int
-cdf_read_header(int fd, cdf_header_t *h)
+cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
 {
-	(void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
 	char buf[512];
-	if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1)
-		return -1;
-	if (read(fd, buf, sizeof(buf)) != sizeof(buf))
+
+	(void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
+	if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1)
 		return -1;
 	cdf_unpack_header(h, buf);
 	cdf_swap_header(h);
 	if (h->h_magic != CDF_MAGIC) {
-		DPRINTF(("Bad magic 0x%x != 0x$x\n", h->h_magic, CDF_MAGIC));
+		DPRINTF(("Bad magic 0x%llx != 0x%llx\n",
+		    (unsigned long long)h->h_magic,
+		    (unsigned long long)CDF_MAGIC));
 		errno = EFTYPE;
 		return -1;
 	}
@@ -248,13 +276,12 @@ cdf_read_header(int fd, cdf_header_t *h)
 
 
 ssize_t
-cdf_read_sector(int fd, void *buf, size_t offs, size_t len,
+cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
     const cdf_header_t *h, cdf_secid_t id)
 {
 	assert((size_t)CDF_SEC_SIZE(h) == len);
-	if (lseek(fd, (off_t)CDF_SEC_POS(h, id), SEEK_SET) == (off_t)-1)
-		return -1;
-	return read(fd, ((char *)buf) + offs, len);
+	return cdf_read(info, (off_t)CDF_SEC_POS(h, id),
+	    ((char *)buf) + offs, len);
 }
 
 ssize_t
@@ -271,24 +298,26 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
  * Read the sector allocation table.
  */
 int
-cdf_read_sat(int fd, cdf_header_t *h, cdf_sat_t *sat)
+cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
 {
 	size_t i, j, k;
 	size_t ss = CDF_SEC_SIZE(h);
 	cdf_secid_t *msa, mid;
+	size_t nsatpersec = (ss / sizeof(mid)) - 1;
 
 	for (i = 0; i < __arraycount(h->h_master_sat); i++)
 		if (h->h_master_sat[i] == CDF_SECID_FREE)
 			break;
 
-	sat->sat_len = (h->h_num_sectors_in_master_sat + i);
+	sat->sat_len = h->h_num_sectors_in_master_sat + i;
+	DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss));
 	if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL)
 		return -1;
 
 	for (i = 0; i < __arraycount(h->h_master_sat); i++) {
 		if (h->h_master_sat[i] < 0)
 			break;
-		if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h,
+		if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
 		    h->h_master_sat[i]) != (ssize_t)ss) {
 			DPRINTF(("Reading sector %d", h->h_master_sat[i]));
 			goto out1;
@@ -305,18 +334,19 @@ cdf_read_sat(int fd, cdf_header_t *h, cdf_sat_t *sat)
 			errno = EFTYPE;
 			goto out2;
 		}
-		if (cdf_read_sector(fd, msa, 0, ss, h, mid) != (ssize_t)ss) {
+		if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) {
 			DPRINTF(("Reading master sector %d", mid));
 			goto out2;
 		}
-		for (k = 0; k < (ss / sizeof(mid)) - 1; k++, i++)
-			if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h,
+		for (k = 0; k < nsatpersec; k++, i++) {
+			if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
 			    CDF_TOLE4(msa[k])) != (ssize_t)ss) {
 				DPRINTF(("Reading sector %d",
 				    CDF_TOLE4(msa[k])));
 				goto out2;
 			}
-		mid = CDF_TOLE4(msa[(ss / sizeof(mid)) - 1]);
+		}
+		mid = CDF_TOLE4(msa[nsatpersec]);
 	}
 	free(msa);
 	return 0;
@@ -328,11 +358,10 @@ out1:
 }
 
 size_t
-cdf_count_chain(const cdf_header_t *h, const cdf_sat_t *sat,
-    cdf_secid_t sid)
+cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
 {
-	size_t i, j, s = CDF_SEC_SIZE(h) / sizeof(cdf_secid_t);
-	cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * s);
+	size_t i, j;
+	cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size);
 
 	DPRINTF(("Chain:"));
 	for (j = i = 0; sid >= 0; i++, j++) {
@@ -354,12 +383,12 @@ cdf_count_chain(const cdf_header_t *h, const cdf_sat_t *sat,
 }
 
 int
-cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
-    cdf_secid_t sid, size_t len, cdf_stream_t *scn)
+cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, cdf_secid_t sid, size_t len, cdf_stream_t *scn)
 {
 	size_t ss = CDF_SEC_SIZE(h), i, j;
 	ssize_t nr;
-	scn->sst_len = cdf_count_chain(h, sat, sid);
+	scn->sst_len = cdf_count_chain(sat, sid, ss);
 	scn->sst_dirlen = len;
 
 	if (scn->sst_len == (size_t)-1)
@@ -370,7 +399,7 @@ cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
 		return -1;
 
 	for (j = i = 0; sid >= 0; i++, j++) {
-		if ((nr = cdf_read_sector(fd, scn->sst_tab, i * ss, ss, h,
+		if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
 		    sid)) != (ssize_t)ss) {
 			if (i == scn->sst_len - 1 && nr > 0) {
 				/* Last sector might be truncated */
@@ -389,7 +418,7 @@ cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
 	return 0;
 out:
 	free(scn->sst_tab);
-	return (size_t)-1;
+	return -1;
 }
 
 int
@@ -398,7 +427,7 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
     cdf_secid_t sid, size_t len, cdf_stream_t *scn)
 {
 	size_t ss = CDF_SHORT_SEC_SIZE(h), i, j;
-	scn->sst_len = cdf_count_chain(h, ssat, sid);
+	scn->sst_len = cdf_count_chain(ssat, sid, CDF_SEC_SIZE(h));
 	scn->sst_dirlen = len;
 
 	if (scn->sst_len == (size_t)-1)
@@ -424,12 +453,12 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
 	return 0;
 out:
 	free(scn->sst_tab);
-	return (size_t)-1;
+	return -1;
 }
 
 int
-cdf_read_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
-    const cdf_sat_t *ssat, const cdf_stream_t *sst,
+cdf_read_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
     cdf_secid_t sid, size_t len, cdf_stream_t *scn)
 {
 
@@ -437,19 +466,19 @@ cdf_read_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
 		return cdf_read_short_sector_chain(h, ssat, sst, sid, len,
 		    scn);
 	else
-		return cdf_read_long_sector_chain(fd, h, sat, sid, len, scn);
+		return cdf_read_long_sector_chain(info, h, sat, sid, len, scn);
 }
 
 int
-cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
-    cdf_dir_t *dir)
+cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, cdf_dir_t *dir)
 {
 	size_t i, j;
 	size_t ss = CDF_SEC_SIZE(h), ns, nd;
 	char *buf;
 	cdf_secid_t sid = h->h_secid_first_directory;
 
-	ns = cdf_count_chain(h, sat, sid);
+	ns = cdf_count_chain(sat, sid, ss);
 	if (ns == (size_t)-1)
 		return -1;
 
@@ -471,7 +500,7 @@ cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
 			errno = EFTYPE;
 			goto out;
 		}
-		if (cdf_read_sector(fd, buf, 0, ss, h, sid) != (ssize_t)ss) {
+		if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) {
 			DPRINTF(("Reading directory sector %d", sid));
 			goto out;
 		}
@@ -494,14 +523,14 @@ out:
 
 
 int
-cdf_read_ssat(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
-    cdf_sat_t *ssat)
+cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, cdf_sat_t *ssat)
 {
 	size_t i, j;
 	size_t ss = CDF_SEC_SIZE(h);
 	cdf_secid_t sid = h->h_secid_first_sector_in_short_sat;
 
-	ssat->sat_len = cdf_count_chain(h, sat, sid);
+	ssat->sat_len = cdf_count_chain(sat, sid, CDF_SEC_SIZE(h));
 	if (ssat->sat_len == (size_t)-1)
 		return -1;
 
@@ -515,7 +544,7 @@ cdf_read_ssat(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
 			errno = EFTYPE;
 			goto out;
 		}
-		if (cdf_read_sector(fd, ssat->sat_tab, i * ss, ss, h, sid) !=
+		if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
 		    (ssize_t)ss) {
 			DPRINTF(("Reading short sat sector %d", sid));
 			goto out;
@@ -529,8 +558,8 @@ out:
 }
 
 int
-cdf_read_short_stream(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
-    const cdf_dir_t *dir, cdf_stream_t *scn)
+cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn)
 {
 	size_t i;
 	const cdf_directory_t *d;
@@ -539,10 +568,11 @@ cdf_read_short_stream(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
 		if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE)
 			break;
 
+	/* If the it is not there, just fake it; some docs don't have it */
 	if (i == dir->dir_len) {
-		DPRINTF(("Cannot find root storage node\n"));
-		errno = EFTYPE;
-		return -1;
+		scn->sst_tab = NULL;
+		scn->sst_len = 0;
+		return 0;
 	}
 	d = &dir->dir_tab[i];
 
@@ -553,7 +583,7 @@ cdf_read_short_stream(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
 		return 0;
 	}
 
-	return  cdf_read_long_sector_chain(fd, h, sat,
+	return  cdf_read_long_sector_chain(info, h, sat,
 	    d->d_stream_first_sector, d->d_size, scn);
 }
 
@@ -567,7 +597,7 @@ cdf_namecmp(const char *d, const uint16_t *s, size_t l)
 }
 
 int
-cdf_read_summary_info(int fd, const cdf_header_t *h,
+cdf_read_summary_info(const cdf_info_t *info, const cdf_header_t *h,
     const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
     const cdf_dir_t *dir, cdf_stream_t *scn)
 {
@@ -587,7 +617,7 @@ cdf_read_summary_info(int fd, const cdf_header_t *h,
 		return -1;
 	}
 	d = &dir->dir_tab[i];
-	return cdf_read_sector_chain(fd, h, sat, ssat, sst,
+	return cdf_read_sector_chain(info, h, sat, ssat, sst,
 	    d->d_stream_first_sector, d->d_size, scn);
 }
 
@@ -848,7 +878,7 @@ cdf_dump_header(const cdf_header_t *h)
 {
 	size_t i;
 
-#define DUMP(a, b) printf("%40.40s = " a "\n", # b, h->h_ ## b)
+#define DUMP(a, b) (void)fprintf(stderr, "%40.40s = " a "\n", # b, h->h_ ## b)
 	DUMP("%d", revision);
 	DUMP("%d", version);
 	DUMP("0x%x", byte_order);
@@ -864,24 +894,26 @@ cdf_dump_header(const cdf_header_t *h)
 	for (i = 0; i < __arraycount(h->h_master_sat); i++) {
 		if (h->h_master_sat[i] == CDF_SECID_FREE)
 			break;
-		printf("%35.35s[%.3zu] = %d\n",
+		(void)fprintf(stderr, "%35.35s[%.3zu] = %d\n",
 		    "master_sat", i, h->h_master_sat[i]);
 	}
 }
 
 void
-cdf_dump_sat(const char *prefix, const cdf_header_t *h, const cdf_sat_t *sat)
+cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size)
 {
-	size_t i, j, s = CDF_SEC_SIZE(h) / sizeof(cdf_secid_t);
+	size_t i, j, s = size / sizeof(cdf_secid_t);
 
 	for (i = 0; i < sat->sat_len; i++) {
-		printf("%s[%zu]:\n", prefix, i);
+		(void)fprintf(stderr, "%s[%zu]:\n%.6d: ", prefix, i, i * s);
 		for (j = 0; j < s; j++) {
-			printf("%5d, ", CDF_TOLE4(sat->sat_tab[s * i + j]));
+			(void)fprintf(stderr, "%5d, ",
+			    CDF_TOLE4(sat->sat_tab[s * i + j]));
 			if ((j + 1) % 10 == 0)
-				printf("\n");
+				(void)fprintf(stderr, "\n%.6d: ",
+				    i * s + j + 1);
 		}
-		printf("\n");
+		(void)fprintf(stderr, "\n");
 	}
 }
 
@@ -891,17 +923,17 @@ cdf_dump(void *v, size_t len)
 	size_t i, j;
 	unsigned char *p = v;
 	char abuf[16];
-	printf("%.4x: ", 0);
+	(void)fprintf(stderr, "%.4x: ", 0);
 	for (i = 0, j = 0; i < len; i++, p++) {
-		printf("%.2x ", *p);
+		(void)fprintf(stderr, "%.2x ", *p);
 		abuf[j++] = isprint(*p) ? *p : '.';
 		if (j == 16) {
 			j = 0;
 			abuf[15] = '\0';
-			printf("%s\n%.4x: ", abuf, i + 1);
+			(void)fprintf(stderr, "%s\n%.4x: ", abuf, i + 1);
 		}
 	}
-	printf("\n");
+	(void)fprintf(stderr, "\n");
 }
 
 void
@@ -913,8 +945,8 @@ cdf_dump_stream(const cdf_header_t *h, const cdf_stream_t *sst)
 }
 
 void
-cdf_dump_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
-    const cdf_sat_t *ssat, const cdf_stream_t *sst,
+cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
     const cdf_dir_t *dir)
 {
 	size_t i, j;
@@ -930,29 +962,30 @@ cdf_dump_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
 		d = &dir->dir_tab[i];
 		for (j = 0; j < sizeof(name); j++)
 			name[j] = (char)CDF_TOLE2(d->d_name[j]);
-		printf("Directory %zu: %s\n", i, name);
+		(void)fprintf(stderr, "Directory %zu: %s\n", i, name);
 		if (d->d_type < __arraycount(types))
-			printf("Type: %s\n", types[d->d_type]);
+			(void)fprintf(stderr, "Type: %s\n", types[d->d_type]);
 		else
-			printf("Type: %d\n", d->d_type);
-		printf("Color: %s\n", d->d_color ? "black" : "red");
-		printf("Left child: %d\n", d->d_left_child);
-		printf("Right child: %d\n", d->d_right_child);
-		printf("Flags: 0x%x\n", d->d_flags);
+			(void)fprintf(stderr, "Type: %d\n", d->d_type);
+		(void)fprintf(stderr, "Color: %s\n",
+		    d->d_color ? "black" : "red");
+		(void)fprintf(stderr, "Left child: %d\n", d->d_left_child);
+		(void)fprintf(stderr, "Right child: %d\n", d->d_right_child);
+		(void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags);
 		cdf_timestamp_to_timespec(&ts, d->d_created);
-		printf("Created %s", ctime(&ts.tv_sec));
+		(void)fprintf(stderr, "Created %s", ctime(&ts.tv_sec));
 		cdf_timestamp_to_timespec(&ts, d->d_modified);
-		printf("Modified %s", ctime(&ts.tv_sec));
-		printf("Stream %d\n", d->d_stream_first_sector);
-		printf("Size %d\n", d->d_size);
+		(void)fprintf(stderr, "Modified %s", ctime(&ts.tv_sec));
+		(void)fprintf(stderr, "Stream %d\n", d->d_stream_first_sector);
+		(void)fprintf(stderr, "Size %d\n", d->d_size);
 		switch (d->d_type) {
 		case CDF_DIR_TYPE_USER_STORAGE:
-			printf("Storage: %d\n", d->d_storage);
+			(void)fprintf(stderr, "Storage: %d\n", d->d_storage);
 			break;
 		case CDF_DIR_TYPE_USER_STREAM:
 			if (sst == NULL)
 				break;
-			if (cdf_read_sector_chain(fd, h, sat, ssat, sst,
+			if (cdf_read_sector_chain(info, h, sat, ssat, sst,
 			    d->d_stream_first_sector, d->d_size, &scn) == -1) {
 				warn("Can't read stream for %s at %d len %d",
 				    name, d->d_stream_first_sector, d->d_size);
@@ -978,33 +1011,38 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
 
 	for (i = 0; i < count; i++) {
 		cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
-		printf("%zu) %s: ", i, buf); 
+		(void)fprintf(stderr, "%zu) %s: ", i, buf); 
 		switch (info[i].pi_type) {
 		case CDF_SIGNED16:
-			printf("signed 16 [%hd]\n", info[i].pi_s16);
+			(void)fprintf(stderr, "signed 16 [%hd]\n",
+			    info[i].pi_s16);
 			break;
 		case CDF_SIGNED32:
-			printf("signed 32 [%d]\n", info[i].pi_s32);
+			(void)fprintf(stderr, "signed 32 [%d]\n",
+			    info[i].pi_s32);
 			break;
 		case CDF_UNSIGNED32:
-			printf("unsigned 32 [%u]\n", info[i].pi_u32);
+			(void)fprintf(stderr, "unsigned 32 [%u]\n",
+			    info[i].pi_u32);
 			break;
 		case CDF_LENGTH32_STRING:
-			printf("string %u [%.*s]\n", info[i].pi_str.s_len,
+			(void)fprintf(stderr, "string %u [%.*s]\n",
+			    info[i].pi_str.s_len,
 			    info[i].pi_str.s_len, info[i].pi_str.s_buf);
 			break;
 		case CDF_FILETIME:
 			tp = info[i].pi_tp;
 			if (tp < 1000000000000000LL) {
 				cdf_print_elapsed_time(buf, sizeof(buf), tp);
-				printf("timestamp %s\n", buf);
+				(void)fprintf(stderr, "timestamp %s\n", buf);
 			} else {
 				cdf_timestamp_to_timespec(&ts, tp);
-				printf("timestamp %s", ctime(&ts.tv_sec));
+				(void)fprintf(stderr, "timestamp %s",
+				    ctime(&ts.tv_sec));
 			}
 			break;
 		case CDF_CLIPBOARD:
-			printf("CLIPBOARD %u\n", info[i].pi_u32);
+			(void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32);
 			break;
 		default:
 			DPRINTF(("Don't know how to deal with %x\n",
@@ -1026,13 +1064,13 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
 	(void)&h;
 	if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1)
 		return;
-	printf("Endian: %x\n", ssi.si_byte_order);
-	printf("Os Version %d.%d\n", ssi.si_os_version & 0xff,
+	(void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order);
+	(void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff,
 		ssi.si_os_version >> 8);
-	printf("Os %d\n", ssi.si_os);
+	(void)fprintf(stderr, "Os %d\n", ssi.si_os);
 	cdf_print_classid(buf, sizeof(buf), &ssi.si_class);
-	printf("Class %s\n", buf);
-	printf("Count %d\n", ssi.si_count);
+	(void)fprintf(stderr, "Class %s\n", buf);
+	(void)fprintf(stderr, "Count %d\n", ssi.si_count);
 	cdf_dump_property_info(info, count);
 	free(info);
 }
@@ -1043,61 +1081,64 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
 int
 main(int argc, char *argv[])
 {
-	int fd, i;
+	int i;
 	cdf_header_t h;
 	cdf_sat_t sat, ssat;
 	cdf_stream_t sst, scn;
 	cdf_dir_t dir;
+	cdf_info_t info;
 
 	if (argc < 2) {
 		(void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
 		return -1;
 	}
 
+	info.i_buf = NULL;
+	info.i_len = 0;
 	for (i = 1; i < argc; i++) {
-		if ((fd = open(argv[1], O_RDONLY)) == -1)
+		if ((info.i_fd = open(argv[1], O_RDONLY)) == -1)
 			err(1, "Cannot open `%s'", argv[1]);
 
-		if (cdf_read_header(fd, &h) == -1)
+		if (cdf_read_header(&info, &h) == -1)
 			err(1, "Cannot read header");
 #ifdef CDF_DEBUG
 		cdf_dump_header(&h);
 #endif
 
-		if (cdf_read_sat(fd, &h, &sat) == -1)
+		if (cdf_read_sat(&info, &h, &sat) == -1)
 			err(1, "Cannot read sat");
 #ifdef CDF_DEBUG
-		cdf_dump_sat("SAT", &h, &sat);
+		cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
 #endif
 
-		if (cdf_read_ssat(fd, &h, &sat, &ssat) == -1)
+		if (cdf_read_ssat(&info, &h, &sat, &ssat) == -1)
 			err(1, "Cannot read ssat");
 #ifdef CDF_DEBUG
-		cdf_dump_sat("SSAT", &h, &ssat);
+		cdf_dump_sat("SSAT", &h, &ssat, CDF_SHORT_SEC_SIZE(&h));
 #endif
 
-		if (cdf_read_dir(fd, &h, &sat, &dir) == -1)
+		if (cdf_read_dir(&info, &h, &sat, &dir) == -1)
 			err(1, "Cannot read dir");
 
-		if (cdf_read_short_stream(fd, &h, &sat, &dir, &sst) == -1)
+		if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst) == -1)
 			err(1, "Cannot read short stream");
 #ifdef CDF_DEBUG
 		cdf_dump_stream(&h, &sst);
 #endif
 
 #ifdef CDF_DEBUG
-		cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir);
+		cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
 #endif
 
 
-		if (cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir,
+		if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
 		    &scn) == -1)
 			err(1, "Cannot read summary info");
 #ifdef CDF_DEBUG
 		cdf_dump_summary_info(&h, &scn);
 #endif
 
-		(void)close(fd);
+		(void)close(info.i_fd);
 	}
 
 	return 0;

+ 24 - 17
src/cdf.h

@@ -242,38 +242,45 @@ typedef struct {
 #define CDF_PROPERTY_SECURITY			0x00000013
 #define CDF_PROPERTY_LOCALE_ID			0x80000000
 
+typedef struct {
+	int i_fd;
+	const unsigned char *i_buf;
+	size_t i_len;
+} cdf_info_t;
+
 struct timespec;
 int cdf_timestamp_to_timespec(struct timespec *, cdf_timestamp_t);
 int cdf_timespec_to_timestamp(cdf_timestamp_t *, const struct timespec *);
-int cdf_read_header(int, cdf_header_t *);
+int cdf_read_header(const cdf_info_t *, cdf_header_t *);
 void cdf_swap_header(cdf_header_t *);
 void cdf_unpack_header(cdf_header_t *, char *);
 void cdf_swap_dir(cdf_directory_t *);
 void cdf_unpack_dir(cdf_directory_t *, char *);
 void cdf_swap_class(cdf_classid_t *);
-ssize_t cdf_read_sector(int, void *, size_t, size_t, const cdf_header_t *,
-    cdf_secid_t);
+ssize_t cdf_read_sector(const cdf_info_t *, void *, size_t, size_t,
+    const cdf_header_t *, cdf_secid_t);
 ssize_t cdf_read_short_sector(const cdf_stream_t *, void *, size_t, size_t,
     const cdf_header_t *, cdf_secid_t);
-int cdf_read_sat(int, cdf_header_t *, cdf_sat_t *);
-size_t cdf_count_chain(const cdf_header_t *, const cdf_sat_t *,
-    cdf_secid_t);
-int cdf_read_long_sector_chain(int, const cdf_header_t *,
+int cdf_read_sat(const cdf_info_t *, cdf_header_t *, cdf_sat_t *);
+size_t cdf_count_chain(const cdf_sat_t *, cdf_secid_t, size_t);
+int cdf_read_long_sector_chain(const cdf_info_t *, const cdf_header_t *,
     const cdf_sat_t *, cdf_secid_t, size_t, cdf_stream_t *);
 int cdf_read_short_sector_chain(const cdf_header_t *, const cdf_sat_t *,
     const cdf_stream_t *, cdf_secid_t, size_t, cdf_stream_t *);
-int cdf_read_sector_chain(int, const cdf_header_t *,
+int cdf_read_sector_chain(const cdf_info_t *, const cdf_header_t *,
     const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *, cdf_secid_t,
     size_t, cdf_stream_t *);
-int cdf_read_dir(int, const cdf_header_t *, const cdf_sat_t *, cdf_dir_t *);
-int cdf_read_ssat(int, const cdf_header_t *, const cdf_sat_t *, cdf_sat_t *);
-int cdf_read_short_stream(int, const cdf_header_t *, const cdf_sat_t *,
-    const cdf_dir_t *, cdf_stream_t *);
+int cdf_read_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
+    cdf_dir_t *);
+int cdf_read_ssat(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
+    cdf_sat_t *);
+int cdf_read_short_stream(const cdf_info_t *, const cdf_header_t *,
+    const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *);
 int cdf_read_property_info(const cdf_stream_t *, uint32_t,
     cdf_property_info_t **, size_t *, size_t *);
-int cdf_read_summary_info(int, const cdf_header_t *, const cdf_sat_t *,
-    const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *,
-    cdf_stream_t *);
+int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *,
+    const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
+    const cdf_dir_t *, cdf_stream_t *);
 int cdf_unpack_summary_info(const cdf_stream_t *, cdf_summary_info_header_t *,
     cdf_property_info_t **, size_t *);
 int cdf_print_classid(char *, size_t, const cdf_classid_t *);
@@ -285,10 +292,10 @@ uint64_t cdf_tole8(uint64_t);
 
 #ifdef CDF_DEBUG
 void cdf_dump_header(const cdf_header_t *);
-void cdf_dump_sat(const char *, const cdf_header_t *, const cdf_sat_t *);
+void cdf_dump_sat(const char *, const cdf_sat_t *, size_t);
 void cdf_dump(void *, size_t);
 void cdf_dump_stream(const cdf_header_t *, const cdf_stream_t *);
-void cdf_dump_dir(int, const cdf_header_t *, const cdf_sat_t *,
+void cdf_dump_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
     const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *);
 void cdf_dump_property_info(const cdf_property_info_t *, size_t);
 void cdf_dump_summary_info(const cdf_header_t *, const cdf_stream_t *);

+ 3 - 2
src/cdf_time.c

@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: cdf_time.c,v 1.5 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: cdf_time.c,v 1.6 2009/03/10 11:44:29 christos Exp $")
 #endif
 
 #include <time.h>
@@ -102,6 +102,7 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
 #ifdef HAVE_STRUCT_TM_TM_ZONE
 	static char UTC[] = "UTC";
 #endif
+	int rdays;
 
 	/* Unit is 100's of nanoseconds */
 	ts->tv_nsec = (t % CDF_TIME_PREC) * 100;
@@ -119,7 +120,7 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
 	// XXX: Approx
 	tm.tm_year = CDF_BASE_YEAR + (t / 365);
 
-	int rdays = cdf_getdays(tm.tm_year);
+	rdays = cdf_getdays(tm.tm_year);
 	t -= rdays;
 	tm.tm_mday = cdf_getday(tm.tm_year, t);
 	tm.tm_mon = cdf_getmonth(tm.tm_year, t);

+ 4 - 1
src/compress.c

@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.61 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.63 2009/03/23 14:21:51 christos Exp $")
 #endif
 
 #include "magic.h"
@@ -76,6 +76,7 @@ private const struct {
 					    /* ...only first file examined */
 	{ "BZh",      3, { "bzip2", "-cd", NULL }, 1 },		/* bzip2-ed */
 	{ "LZIP",     4, { "lzip", "-cdq", NULL }, 1 },
+ 	{ "\3757zXZ\0",6,{ "xz", "-cd", NULL }, 1 },		/* XZ Utils */
 };
 
 private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
@@ -486,6 +487,8 @@ err:
 #else
 		(void)wait(NULL);
 #endif
+		(void) close(fdin[0]);
+	    
 		return n;
 	}
 }

+ 2 - 2
src/file.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: file.c,v 1.130 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.131 2009/02/13 18:48:05 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -61,7 +61,7 @@ FILE_RCSID("@(#)$File: file.c,v 1.130 2009/02/03 20:27:51 christos Exp $")
 #include <wchar.h>
 #endif
 
-#ifdef HAVE_GETOPT_H
+#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION)
 #include <getopt.h>
 #else
 #include "mygetopt.h"

+ 8 - 2
src/file.h

@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.118 2009/02/03 20:27:51 christos Exp $
+ * @(#)$File: file.h,v 1.119 2009/02/04 18:24:32 christos Exp $
  */
 
 #ifndef __file_h__
@@ -387,7 +387,13 @@ protected size_t file_mbswidth(const char *);
 protected const char *file_getbuffer(struct magic_set *);
 protected ssize_t sread(int, void *, size_t, int);
 protected int file_check_mem(struct magic_set *, unsigned int);
-protected int file_looks_utf8(const unsigned char *, size_t, unichar *, size_t *);
+protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
+    size_t *);
+#ifdef __EMX__
+protected int file_os2_apptype(struct magic_set *, const char *, const void *,
+    size_t);
+#endif /* __EMX__ */
+
 
 #ifndef COMPILE_ONLY
 extern const char *file_names[];

+ 9 - 2
src/funcs.c

@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.51 2008/11/07 18:57:28 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.53 2009/04/07 11:07:00 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -303,7 +303,14 @@ file_reset(struct magic_set *ms)
 		file_error(ms, 0, "no magic files loaded");
 		return -1;
 	}
-	ms->o.buf = NULL;
+	if (ms->o.buf) {
+		free(ms->o.buf);
+		ms->o.buf = NULL;
+	}
+	if (ms->o.pbuf) {
+		free(ms->o.pbuf);
+		ms->o.pbuf = NULL;
+	}
 	ms->event_flags &= ~EVENT_HAD_ERR;
 	ms->error = -1;
 	return 0;

+ 2 - 2
src/getopt_long.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: getopt_long.c,v 1.5 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: getopt_long.c,v 1.6 2009/02/13 18:48:05 christos Exp $")
 #endif	/* lint */
 
 #include <assert.h>
@@ -42,7 +42,7 @@ FILE_RCSID("@(#)$File: getopt_long.c,v 1.5 2009/02/03 20:27:51 christos Exp $")
 #define warnx printf
 #endif
 #include <errno.h>
-#ifdef HAVE_GETOPT_H
+#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION)
 #include <getopt.h>
 #else
 #include "mygetopt.h"

+ 4 - 30
src/magic.c

@@ -28,7 +28,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25:41 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -57,10 +57,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $")
 #include <unistd.h>	/* for read() */
 #endif
 
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
-
 #include <netinet/in.h>		/* for byte swapping */
 
 #include "patchlevel.h"
@@ -74,12 +70,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $")
 #endif
 #endif
 
-#ifdef __EMX__
-private char *apptypeName = NULL;
-protected int file_os2_apptype(struct magic_set *ms, const char *fn,
-    const void *buf, size_t nb);
-#endif /* __EMX__ */
-
 private void free_mlist(struct mlist *);
 private void close_and_restore(const struct magic_set *, const char *, int,
     const struct stat *);
@@ -297,26 +287,10 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
 
 		errno = 0;
 		if ((fd = open(inname, flags)) < 0) {
-#ifdef __CYGWIN__
-			/* FIXME: Do this with EXEEXT from autotools */
-			size_t len = strlen(inname) + 5;
-			char *tmp = alloca(len);
-			(void)strlcat(strlcpy(tmp, inname, len), ".exe", len);
-			if ((fd = open(tmp, flags)) < 0) {
-#endif
-				if (unreadable_info(ms, sb.st_mode,
-#ifdef __CYGWIN
-						    tmp
-#else
-						    inname
-#endif
-						    ) == -1)
-					goto done;
-				rv = 0;
+			if (unreadable_info(ms, sb.st_mode, inname) == -1)
 				goto done;
-#ifdef __CYGWIN__
-			}
-#endif
+			rv = 0;
+			goto done;
 		}
 #ifdef O_NONBLOCK
 		if ((flags = fcntl(fd, F_GETFL)) != -1) {

+ 5 - 2
src/patchlevel.h

@@ -1,11 +1,14 @@
 #define	FILE_VERSION_MAJOR	5
-#define	patchlevel		0
+#define	patchlevel		1
 
 /*
  * Patchlevel file for Ian Darwin's MAGIC command.
- * $File: patchlevel.h,v 1.71 2009/01/21 19:09:42 christos Exp $
+ * $File: patchlevel.h,v 1.72 2009/04/30 21:20:15 christos Exp $
  *
  * $Log: patchlevel.h,v $
+ * Revision 1.72  2009/04/30 21:20:15  christos
+ * 5.01 we are almost here.
+ *
  * Revision 1.71  2009/01/21 19:09:42  christos
  * file 5.0
  *

+ 48 - 29
src/readcdf.c

@@ -26,7 +26,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.11 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.15 2009/04/30 21:03:26 christos Exp $")
 #endif
 
 #include <stdlib.h>
@@ -75,9 +75,23 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
 			if (len > 1) {
 				s = info[i].pi_str.s_buf;
 				if (NOTMIME(ms)) {
-					if (file_printf(ms, ", %s: %.*s", buf,
-					    len, s) == -1)
-						return -1;
+					char vbuf[1024];
+					size_t j;
+					for (j = 0; j < sizeof(vbuf) && len--;
+					    j++, s++) {
+						if (*s == '\0')
+							break;
+						if (isprint((unsigned char)*s))
+							vbuf[j] = *s;
+					}
+					if (j == sizeof(vbuf))
+						--j;
+					vbuf[j] = '\0';
+					if (vbuf[0]) {
+						if (file_printf(ms, ", %s: %s",
+						    buf, vbuf) == -1)
+							return -1;
+					}
 				} else if (info[i].pi_id == 
 					CDF_PROPERTY_NAME_OF_APPLICATION) {
 					if (strstr(s, "Word"))
@@ -115,7 +129,6 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
 		case CDF_CLIPBOARD:
 			break;
 		default:
-			file_error(ms, 0, "Internal parsing error");
 			return -1;
 		}
 	}
@@ -183,66 +196,64 @@ protected int
 file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
     size_t nbytes)
 {
+	cdf_info_t info;
 	cdf_header_t h;
 	cdf_sat_t sat, ssat;
 	cdf_stream_t sst, scn;
 	cdf_dir_t dir;
 	int i;
-	(void)&nbytes;
-	(void)&buf;
+	const char *expn = "";
 
+	info.i_fd = fd;
+	info.i_buf = buf;
+	info.i_len = nbytes;
 	if (ms->flags & MAGIC_APPLE)
 		return 0;
-	if (cdf_read_header(fd, &h) == -1)
+	if (cdf_read_header(&info, &h) == -1)
 		return 0;
 #ifdef CDF_DEBUG
 	cdf_dump_header(&h);
 #endif
 
-	if (cdf_read_sat(fd, &h, &sat) == -1) {
-		file_error(ms, errno, "Can't read SAT");
+	if (cdf_read_sat(&info, &h, &sat) == -1) {
+		expn = "Can't read SAT";
 		return -1;
 	}
 #ifdef CDF_DEBUG
-	cdf_dump_sat("SAT", &h, &sat);
+	cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
 #endif
 
-	if ((i = cdf_read_ssat(fd, &h, &sat, &ssat)) == -1) {
-		file_error(ms, errno, "Can't read SAT");
+	if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
+		expn = "Can't read SSAT";
 		goto out1;
 	}
 #ifdef CDF_DEBUG
-	cdf_dump_sat("SSAT", &h, &ssat);
+	cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
 #endif
 
-	if ((i = cdf_read_dir(fd, &h, &sat, &dir)) == -1) {
-		file_error(ms, errno, "Can't read directory");
+	if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
+		expn = "Can't read directory";
 		goto out2;
 	}
 
-	if ((i = cdf_read_short_stream(fd, &h, &sat, &dir, &sst)) == -1) {
-		file_error(ms, errno, "Cannot read short stream");
+	if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
+		expn = "Cannot read short stream";
 		goto out3;
 	}
-
 #ifdef CDF_DEBUG
-	cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir);
-#endif
-	if ((i = cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir, &scn))
-	    == -1) {
-		/* Some files don't have summary info! */
-#ifdef notyet
-		file_error(ms, errno, "Can't read summary_info");
-#else
-		i = 0;
+	cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
 #endif
+
+	if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
+	    &scn)) == -1) {
+		expn = "";
 		goto out4;
 	}
 #ifdef CDF_DEBUG
 	cdf_dump_summary_info(&h, &scn);
 #endif
 	if ((i = cdf_file_summary_info(ms, &scn)) == -1)
-		file_error(ms, errno, "Can't expand summary_info");
+		expn = "Can't expand summary_info";
 	free(scn.sst_tab);
 out4:
 	free(sst.sst_tab);
@@ -252,5 +263,13 @@ out2:
 	free(ssat.sat_tab);
 out1:
 	free(sat.sat_tab);
+	if (i != 1) {
+		if (file_printf(ms, "CDF V2 Document") == -1)
+			return -1;
+		if (*expn)
+			if (file_printf(ms, ", corrupt: %s", expn) == -1)
+				return -1;
+		i = 1;
+	}
 	return i;
 }

+ 13 - 11
src/softmagic.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.133 2008/11/07 22:50:37 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.135 2009/03/27 22:42:49 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -256,11 +256,14 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
 				 * make sure that we have a separator first.
 				 */
 				if (*m->desc) {
-					printed_something = 1;
 					if ((e = handle_annotation(ms, m)) != 0)
 						return e;
-					if (print_sep(ms, firstline) == -1)
-						return -1;
+					if (!printed_something) {
+						printed_something = 1;
+						if (print_sep(ms, firstline)
+						    == -1)
+							return -1;
+					}
 				}
 				/*
 				 * This continuation matched.  Print
@@ -338,14 +341,13 @@ strndup(const char *str, size_t n)
 	size_t len;
 	char *copy;
 
-	len = strlen(str);
-	if (len > n)
-		len = n;
-	if (!(copy = malloc(len + 1)))
-		return (NULL);
-	(void) memcpy(copy, str, len + 1);
+	for (len = 0; len < n && str[len]; len++)
+		continue;
+	if ((copy = malloc(len + 1)) == NULL)
+		return NULL;
+	(void)memcpy(copy, str, len);
 	copy[len] = '\0';
-	return (copy);
+	return copy;
 }
 #endif /* HAVE_STRNDUP */
 

+ 1 - 0
src/strlcat.c

@@ -17,6 +17,7 @@
  */
 
 /* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
+#include "file.h"
 
 #include <sys/types.h>
 #include <string.h>

+ 1 - 0
src/strlcpy.c

@@ -17,6 +17,7 @@
  */
 
 /* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
+#include "file.h"
 
 #include <sys/types.h>
 #include <string.h>

+ 4 - 1
tests/Makefile.in

@@ -14,7 +14,6 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@@ -62,6 +61,7 @@ DIST_SOURCES = test.c
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
@@ -81,6 +81,7 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
 ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
@@ -103,6 +104,7 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
 MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -112,6 +114,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@