conformance.diff   [plain text]


diff -ru ../old/doc/file.man ./doc/file.man
--- ../old/doc/file.man	2004-12-27 16:16:19.000000000 -0800
+++ ./doc/file.man	2004-12-29 21:23:24.000000000 -0800
@@ -6,7 +6,7 @@
 .SH SYNOPSIS
 .B file
 [
-.B \-bchikLnNprsvz
+.B \-bcdhikLnNprsvz
 ]
 [
 .B \-f
@@ -17,6 +17,10 @@
 .I separator
 ]
 [
+.B \-M 
+.I magicfiles
+]
+[
 .B \-m 
 .I magicfiles
 ]
@@ -193,7 +197,7 @@
 .I POSIXLY_CORRECT
 is not defined.
 .TP 8
-.B "\-i, \-\-mime"
+.B "\-I, \-\-mime"
 Causes the file command to output mime type strings rather than the more
 traditional human readable ones. Thus it may say
 ``text/plain; charset=us-ascii''
@@ -205,6 +209,9 @@
 ``magic'' file.
 (See ``FILES'' section, below).
 .TP 8
+.B "\-i"
+If the file is a regular file do not classify its contents.
+.TP 8
 .B "\-k, \-\-keep\-going"
 Don't stop at the first match, keep going.
 .TP 8
@@ -220,13 +220,20 @@
 Specify an alternate list of files containing magic numbers.
 This can be a single file, or a colon-separated list of files.
 If a compiled magic file is found alongside, it will be used instead.
-With the \-i or \-\-mime option, the program adds ".mime" to each file name.
+With the \-I or \-\-mime option, the program adds ".mime" to each file name.
+.TP 8
+.BI "\-m" " list"
+Like \-m, except the default rules are not applied.
 .TP 8
 .B "\-n, \-\-no\-buffer"
 Force stdout to be flushed after checking each file.
 This is only useful if checking a list of files.
 It is intended to be used by programs that want filetype output from a pipe.
 .TP 8
+.B "\-d"
+Apply default system tests, this is the default if neither \-m nor \-M are 
+supplied.
+.TP 8
 .B "\-N, \-\-no\-pad"
 Don't pad filenames so that they align in the output.
 .TP 8
@@ -240,11 +257,7 @@
 never read them.
 .TP 8
 .B "\-r, \-\-raw"
-Don't translate unprintable characters to \eooo.
-Normally
-.B file
-translates unprintable characters to their octal representation.
-.TP 8
+No operation, included for historical compatability.
 .B "\-s, \-\-special\-files"
 Normally,
 .B file
@@ -312,16 +325,61 @@
 and
 .B h
 options.
+.SH LEGACY 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 LEGACY DESCRIPTION
+As above, except:
+.TP 8
+.B "\-i, \-\-mime"
+Causes the file command to output mime type strings rather than the more
+traditional human readable ones. Thus it may say
+``text/plain; charset=us-ascii''
+rather
+than ``ASCII text''.
+In order for this option to work, file changes the way
+it handles files recognised by the command itself (such as many of the
+text file types, directories etc), and makes use of an alternative
+``magic'' file.
+(See ``FILES'' section, below).
+.TP 8
+.B "\-r, \-\-raw"
+Don't translate unprintable characters to \eooo.
+Normally
+.B file
+translates unprintable characters to their octal representation.
+.B 
 .SH SEE ALSO
 .BR magic (__FSECTION__)
 \- description of magic file format.
 .br
-.BR strings (1), " od" (1), " hexdump(1)"
+.BR strings (1), " od" (1), " hexdump(1)", " compat(5)"
 \- tools for examining non-textfiles.
 .SH STANDARDS CONFORMANCE
-This program is believed to exceed the System V Interface Definition
-of FILE(CMD), as near as one can determine from the vague language
-contained therein. 
+This program conforms to
+.St -susv3
 Its behaviour is mostly compatible with the System V program of the same name.
 This version knows more magic, however, so it will produce
 different (albeit more accurate) output in many cases. 
Only in ./src: .gdb_history
diff -ru ../old/src/apprentice.c ./src/apprentice.c
--- ../old/src/apprentice.c	2004-12-27 16:16:19.000000000 -0800
+++ ./src/apprentice.c	2004-12-27 17:01:50.000000000 -0800
@@ -713,13 +713,64 @@
 #define NLESTRING16	10
 #define NSEARCH		6
 
-	if (*l == 'u') {
-		++l;
-		m->flag |= UNSIGNED;
-	}
+	switch (*l) {
+	case 'd':	/* POSIX abbreviation for signed decimal */
+		if (!isalpha((unsigned char)l[1])) {
+			m->type = FILE_LONG;
+			++l;
+		}
+		if (isdigit((unsigned char)*l)) {
+			switch(*l) {
+			case '1':
+				m->type = FILE_BYTE;
+				++l;
+				break;
+			case '2':
+				m->type = FILE_SHORT;
+				++l;
+				break;
+			case '4':
+				++l;
+				break;
+			}
+		}
+		break;
 
+	case 's':	/* POSIX abbreviation for string */
+		if (!isalpha((unsigned char)l[1])) {
+			m->type = FILE_STRING;
+			++l;
+		}
+		break;
+
+	case 'u':	/* POSIX abbreviation for unsigned decimal */
+ 		++l;
+ 		m->flag |= UNSIGNED;
+		if (!isalpha((unsigned char)*l)) {
+			m->type = FILE_LONG;
+		}
+		if (isdigit((unsigned char)*l)) {
+			switch(*l) {
+			case '1':
+				m->type = FILE_BYTE;
+				++l;
+				break;
+			case '2':
+				m->type = FILE_SHORT;
+				++l;
+				break;
+			case '4':
+				++l;
+				break;
+			}
+		}
+		break;
+	}
+	
 	/* get type, skip it */
-	if (strncmp(l, "char", NBYTE)==0) {	/* HP/UX compat */
+	if (m->type) {
+		/* POSIX got here first */
+	} else if (strncmp(l, "char", NBYTE)==0) {	/* HP/UX compat */
 		m->type = FILE_BYTE;
 		l += NBYTE;
 	} else if (strncmp(l, "byte", NBYTE)==0) {
@@ -1038,6 +989,10 @@
 				*p++ = '\r';
 				break;
 
+			case 'a':
+				*p++ = '\a';
+				break;
+
 			case 'b':
 				*p++ = '\b';
 				break;
--- src/file.c.orig	2005-10-17 11:41:44.000000000 -0700
+++ src/file.c	2007-02-02 19:41:35.000000000 -0800
@@ -70,6 +70,12 @@
 
 #include "patchlevel.h"
 
+#ifdef __APPLE__
+#include "get_compat.h"
+#else
+#define COMPAT_MODE(func, mode) 1
+#endif
+
 #ifndef	lint
 FILE_RCSID("@(#)$Id: file.c,v 1.100 2005/10/17 18:41:44 christos Exp $")
 #endif	/* lint */
@@ -82,6 +88,7 @@
 #endif
 
 # define USAGE  "Usage: %s [-bcik" SYMLINKFLAG "nNsvz] [-f namefile] [-F separator] [-m magicfiles] file...\n       %s -C -m magicfiles\n"
+# define USAGE2 "Usage: %s [-bciIk" SYMLINKFLAG "nNsvz] [-f namefile] [-F separator] [-m magicfiles] file...\n       %s -C -m magicfiles\n"
 
 #ifndef MAXPATHLEN
 #define	MAXPATHLEN	512
@@ -89,6 +96,7 @@
 
 private int 		/* Global command-line options 		*/
 	bflag = 0,	/* brief output format	 		*/
+	dflag = 0,	/* POSIX 'd' option -- use default magic file */
 	nopad = 0,	/* Don't pad output			*/
 	nobuffer = 0;   /* Do not buffer stdout 		*/
 
@@ -123,10 +131,10 @@
 {
 	int c;
 	int action = 0, didsomefiles = 0, errflg = 0;
-	int flags = 0;
+	int flags = (COMPAT_MODE("bin/file", "unix2003") ? MAGIC_SYMLINK : 0);
 	char *home, *usermagic;
 	struct stat sb;
-#define OPTSTRING	"bcCdf:F:hikLm:nNprsvz"
+#define OPTSTRING	(COMPAT_MODE("bin/file", "unix2003") ? "bcCdDf:F:hiIkLm:M:nNprsvz": "bcCdf:F:hikLm:nNprsvz")
 #ifdef HAVE_GETOPT_LONG
 	int longindex;
 	private struct option long_options[] =
@@ -135,10 +143,11 @@
 		{"help", 0, 0, 0},
 		{"brief", 0, 0, 'b'},
 		{"checking-printout", 0, 0, 'c'},
-		{"debug", 0, 0, 'd'},
+		/* 'D' is always debug, 'd' is frequently something else */
+		{"debug", 0, 0, 'D'},
 		{"files-from", 1, 0, 'f'},
 		{"separator", 1, 0, 'F'},
-		{"mime", 0, 0, 'i'},
+		{"mime", 0, 0, 'I'},
 		{"keep-going", 0, 0, 'k'},
 #ifdef S_IFLNK
 		{"dereference", 0, 0, 'L'},
@@ -191,6 +200,11 @@
 #ifdef S_IFLNK
 	flags |= getenv("POSIXLY_CORRECT") ? MAGIC_SYMLINK : 0;
 #endif
+
+	if (COMPAT_MODE("bin/file", "unix2003")) {
+	    flags |= MAGIC_RAW;
+	}
+
 #ifndef HAVE_GETOPT_LONG
 	while ((c = getopt(argc, argv, OPTSTRING)) != -1)
 #else
@@ -214,6 +228,11 @@
 			action = FILE_COMPILE;
 			break;
 		case 'd':
+			if (COMPAT_MODE("bin/file", "unix2003")) {
+			    ++dflag;
+			    break;
+			}
+		case 'D':
 			flags |= MAGIC_DEBUG|MAGIC_CHECK;
 			break;
 		case 'f':
@@ -227,13 +246,41 @@
 			separator = optarg;
 			break;
 		case 'i':
+			if (COMPAT_MODE("bin/file", "unix2003")) {
+			    flags |= MAGIC_REGULAR;
+			    break;
+			}
+		case 'I':
 			flags |= MAGIC_MIME;
 			break;
 		case 'k':
 			flags |= MAGIC_CONTINUE;
 			break;
 		case 'm':
-			magicfile = optarg;
+			if (magicfile == default_magicfile ||
+				magicfile == usermagic)
+				magicfile = optarg;
+			else {
+				char *newmagicfile = malloc(strlen(magicfile)+strlen(separator)+strlen(optarg)+1);
+				strcpy(newmagicfile, magicfile);
+				strcat(newmagicfile, separator);
+				strcat(newmagicfile, optarg);
+				magicfile = newmagicfile;
+			}
+			break;
+		case 'M':
+			if (magicfile == default_magicfile ||
+				magicfile == usermagic)
+				magicfile = optarg;
+			else {
+				char *newmagicfile = malloc(strlen(magicfile)+strlen(separator)+strlen(optarg)+1);
+				strcpy(newmagicfile, magicfile);
+				strcat(newmagicfile, separator);
+				strcat(newmagicfile, optarg);
+				magicfile = newmagicfile;
+			}
+			if (!dflag)
+				flags |= MAGIC_NOASCII;
 			break;
 		case 'n':
 			++nobuffer;
@@ -497,7 +544,7 @@
 private void
 usage(void)
 {
-	(void)fprintf(stderr, USAGE, progname, progname);
+	(void)fprintf(stderr, COMPAT_MODE("bin/file", "unix2003") ? USAGE2 : USAGE, progname, progname);
 #ifdef HAVE_GETOPT_LONG
 	(void)fputs("Try `file --help' for more information.\n", stderr);
 #endif
@@ -508,7 +555,39 @@
 private void
 help(void)
 {
-	(void)puts(
+	if (COMPAT_MODE("bin/file", "unix2003")) {
+	    (void)puts(
+"Usage: file [OPTION]... [FILE]...\n"
+"Determine file type of FILEs.\n"
+"\n"
+"  -m, --magic-file LIST      use LIST as a colon-separated list of magic\n"
+"                               number files\n"
+"  -M LIST                    use LIST as a colon-separated list of magic\n"
+"                               number files in place of default\n"
+"  -z, --uncompress           try to look inside compressed files\n"
+"  -b, --brief                do not prepend filenames to output lines\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"
+"                               before installing it\n"
+"  -d                         use default magic 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"
+"  -I, --mime                 output mime type strings\n"
+"  -h                         when a symbolic link is encountered\n"
+"                               identify the file as a symbolic link\n"
+"  -k, --keep-going           don't stop at the first match\n"
+"  -L, --dereference          causes symlinks to be followed\n"
+"  -n, --no-buffer            do not buffer output\n"
+"  -N, --no-pad               do not pad output\n"
+"  -p, --preserve-date        preserve access times on files\n"
+"  -r, --raw                  don't translate unprintable chars to \\ooo\n"
+"  -s, --special-files        treat special (block/char devices) files as\n"
+"                             ordinary ones\n"
+"      --help                 display this help and exit\n"
+"      --version              output version information and exit\n"
+);
+	} else {
+	    puts(
 "Usage: file [OPTION]... [FILE]...\n"
 "Determine file type of FILEs.\n"
 "\n"
@@ -533,6 +612,7 @@
 "      --help                 display this help and exit\n"
 "      --version              output version information and exit\n"
 );
+	}
 	exit(0);
 }
 #endif
diff -ru ../old/src/fsmagic.c ./src/fsmagic.c
--- ../old/src/fsmagic.c	2004-12-27 16:16:19.000000000 -0800
+++ ./src/fsmagic.c	2004-12-28 21:10:03.000000000 -0800
@@ -56,6 +56,12 @@
 #endif
 #undef HAVE_MAJOR
 
+#ifdef __APPLE__
+#include "get_compat.h"
+#else
+#define COMPAT_MODE(func, mode) 1
+#endif
+
 #ifndef	lint
 FILE_RCSID("@(#)$Id: fsmagic.c,v 1.46 2005/06/25 15:52:14 christos Exp $")
 #endif	/* lint */
@@ -84,6 +90,14 @@
 #endif
 	ret = stat(fn, sb);	/* don't merge into if; see "ret =" above */
 
+#ifdef	S_IFLNK
+	/* POSIX says pretend symlinks to nonexistant files
+	  have the -h option */
+	if (ret && (ms->flags & MAGIC_SYMLINK) != 0) {
+	    ret = lstat(fn, sb);
+	}
+#endif
+
 	if (ret) {
 		if (ms->flags & MAGIC_ERROR) {
 			file_error(ms, errno, "cannot stat `%s'", fn);
@@ -214,12 +228,22 @@
 		    if (stat(buf, &tstatbuf) < 0) {
 			    if (ms->flags & MAGIC_ERROR) {
 				    file_error(ms, errno, 
-					"broken symbolic link to `%s'", buf);
+					"broken symbolic link to %s", buf);
 				    return -1;
 			    } 
-			    if (file_printf(ms, "broken symbolic link to `%s'",
-				buf) == -1)
-				    return -1;
+			    int fp_rc = -1;
+			    if (COMPAT_MODE("bin/file", "unix2003")) {
+				/* Posix required diagnostic */
+				fp_rc = file_printf(ms, "cannot open `%s' (%s)",
+				  fn, buf);
+			    } else {
+				fp_rc = file_printf(ms,
+				  "broken symbolic link to %s",
+				  buf);
+			    }
+			    if (fp_rc == -1) {
+				return -1;
+			    }
 			    return 1;
 		    }
 		}
@@ -249,12 +273,12 @@
 			if (stat(tmp, &tstatbuf) < 0) {
 				if (ms->flags & MAGIC_ERROR) {
 					file_error(ms, errno, 
-					    "broken symbolic link to `%s'",
+					    "broken symbolic link to %s",
 					    buf);
 					return -1;
 				}
 				if (file_printf(ms,
-				    "broken symbolic link to `%s'", buf) == -1)
+				    "broken symbolic link to %s", buf) == -1)
 					return -1;
 				return 1;
 			}
@@ -268,7 +292,7 @@
 			ms->flags |= MAGIC_SYMLINK;
 			return p != NULL ? 1 : -1;
 		} else { /* just print what it points to */
-			if (file_printf(ms, "symbolic link to `%s'",
+			if (file_printf(ms, "symbolic link to %s",
 			    buf) == -1)
 				return -1;
 		}
@@ -283,6 +307,11 @@
 #endif
 #endif
 	case S_IFREG:
+		if (ms->flags & MAGIC_REGULAR) {
+			if (file_printf(ms, "regular file") == -1)
+				return -1;
+			return 1;
+		}
 		break;
 	default:
 		file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
diff -ru ../old/src/funcs.c ./src/funcs.c
--- ../old/src/funcs.c	2004-12-27 16:16:19.000000000 -0800
+++ ./src/funcs.c	2004-12-27 18:23:47.000000000 -0800
@@ -128,7 +128,7 @@
 	    /* try tests in /etc/magic (or surrogate magic file) */
 	    if ((m = file_softmagic(ms, buf, nb)) == 0) {
 		/* try known keywords, check whether it is ASCII */
-		if ((m = file_ascmagic(ms, buf, nb)) == 0) {
+		if ((ms->flags & MAGIC_NOASCII) || (m = file_ascmagic(ms, buf, nb)) == 0) {
 		    /* abandon hope, all ye who remain here */
 		    if (file_printf(ms, ms->flags & MAGIC_MIME ?
 			(nb ? "application/octet-stream" :
diff -ru ../old/src/magic.c ./src/magic.c
--- ../old/src/magic.c	2004-12-27 16:16:19.000000000 -0800
+++ ./src/magic.c	2004-12-28 21:40:48.000000000 -0800
@@ -65,6 +65,12 @@
 FILE_RCSID("@(#)$Id: magic.c,v 1.32 2005/10/17 15:31:10 christos Exp $")
 #endif	/* lint */
 
+#ifdef __APPLE__
+#include "get_compat.h"
+#else
+#define COMPAT_MODE(func, mode) 1
+#endif
+
 #ifdef __EMX__
 private char *apptypeName = NULL;
 protected int file_os2_apptype(struct magic_set *ms, const char *fn,
@@ -252,19 +258,26 @@
 	    if ((fd = open(tmp, O_RDONLY|O_BINARY)) < 0) {
 #endif
 		/* We cannot open it, but we were able to stat it. */
-		if (sb.st_mode & 0222)
-			if (file_printf(ms, "writable, ") == -1)
-				goto done;
-		if (sb.st_mode & 0111)
-			if (file_printf(ms, "executable, ") == -1)
-				goto done;
-		if (S_ISREG(sb.st_mode))
-			if (file_printf(ms, "regular file, ") == -1)
-				goto done;
-		if (file_printf(ms, "no read permission") == -1)
-			goto done;
-		rv = 0;
-		goto done;
+		if (COMPAT_MODE("bin/file", "unix2003")) {
+		    if (file_printf(ms, "cannot open %s: %s", inname, strerror(errno)) == -1)
+		    	goto done;
+		    rv = 0;
+		    goto done;
+		} else {
+			if (sb.st_mode & 0222)
+				if (file_printf(ms, "writable, ") == -1)
+					goto done;
+			if (sb.st_mode & 0111)
+				if (file_printf(ms, "executable, ") == -1)
+					goto done;
+			if (S_ISREG(sb.st_mode))
+				if (file_printf(ms, "regular file, ") == -1)
+					goto done;
+			if (file_printf(ms, "no read permission") == -1)
+				goto done;
+			rv = 0;
+			goto done;
+		}
 #ifdef __CYGWIN__
 	    }
 #endif
diff -ru ../old/src/magic.h ./src/magic.h
--- ../old/src/magic.h	2004-12-27 16:16:19.000000000 -0800
+++ ./src/magic.h	2004-12-27 18:33:57.000000000 -0800
@@ -40,6 +40,8 @@
 #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_NOASCII		0x400	/* Suppress internal magic */
+#define	MAGIC_REGULAR		0x800	/* Report as regular file */
 
 #ifdef __cplusplus
 extern "C" {
diff -ru ../old/src/names.h ./src/names.h
--- ../old/src/names.h	2004-12-27 16:16:19.000000000 -0800
+++ ./src/names.h	2004-12-27 18:35:01.000000000 -0800
@@ -61,9 +61,9 @@
 	const char *human;
 	const char *mime;
 } types[] = {
-	{ "C program",					"text/x-c", },
+	{ "c program",					"text/x-c", },
 	{ "C++ program",				"text/x-c++" },
-	{ "FORTRAN program",				"text/x-fortran" },
+	{ "fortran program",				"text/x-fortran" },
 	{ "make commands",				"text/x-makefile" },
 	{ "PL/1 program",				"text/x-pl1" },
 	{ "assembler program",				"text/x-asm" },
diff -ru ../old/src/readelf.h ./src/readelf.h
--- ../old/src/readelf.h	2004-12-27 16:16:19.000000000 -0800
+++ ./src/readelf.h	2004-12-29 21:50:52.000000000 -0800
@@ -37,6 +37,7 @@
 #if HAVE_STDINT_H
 #include <stdint.h>
 #endif
+#include <sys/types.h>
 
 typedef uint32_t	Elf32_Addr;
 typedef uint32_t	Elf32_Off;