conformance.diff   [plain text]


--- doc/file.man.orig	2008-07-16 14:56:20.000000000 -0700
+++ doc/file.man	2008-07-16 17:41:02.000000000 -0700
@@ -7,12 +7,13 @@
 .Nd determine file type
 .Sh SYNOPSIS
 .Nm
-.Op Fl bchikLnNprsvz
+.Op Fl bcdDhiIkLnNprsvz
 .Op Fl -mime-type
 .Op Fl -mime-encoding
 .Op Fl f Ar namefile
 .Op Fl F Ar separator
 .Op Fl m Ar magicfiles
+.Op Fl M Ar magicfiles
 .Ar file
 .Nm
 .Fl C
@@ -170,6 +171,12 @@
 Write a
 .Pa magic.mgc
 output file that contains a pre-parsed version of the magic file or directory.
+.It Fl d
+Apply the default system tests; this is the default behavior unless
+.Fl M
+is specified.
+.It Fl D
+Print debugging messages.
 .It Fl e , -exclude Ar testname
 Exclude the test named in
 .Ar testname
@@ -215,11 +222,10 @@
 .Sq \&: .
 .It Fl h , -no-dereference
 option causes symlinks not to be followed
-(on systems that support symbolic links). This is the default if the
-environment variable
-.Dv POSIXLY_CORRECT
-is not defined.
-.It Fl i , -mime
+(on systems that support symbolic links).
+.It Fl i
+If the file is a regular file, do not classify its contents.
+.It Fl I , -mime
 Causes the file command to output mime type strings rather than the more
 traditional human readable ones. Thus it may say
 .Sq text/plain; charset=us-ascii
@@ -233,7 +239,7 @@
 (See the FILES section, below).
 .It Fl -mime-type , -mime-encoding
 Like
-.Fl i ,
+.Fl I ,
 but print only the specified element(s).
 .It Fl k , -keep-going
 Don't stop at the first match, keep going. Subsequent matches will be
@@ -247,13 +253,17 @@
 option causes symlinks to be followed, as the like-named option in
 .Xr ls 1
 (on systems that support symbolic links).
-This is the default if the environment variable
-.Dv POSIXLY_CORRECT
-is defined.
+This is the default behavior.
 .It Fl m , -magic-file Ar list
 Specify an alternate list of files and directories containing magic.
 This can be a single item, or a colon-separated list.
 If a compiled magic file is found alongside a file or directory, it will be used instead.
+.It Fl M Ar list
+Like
+.Fl m ,
+except that the default rules are not applied unless
+.Fl d
+is specified.
 .It Fl n , -no-buffer
 Force stdout to be flushed after checking each file.
 This is only useful if checking a list of files.
@@ -269,10 +279,7 @@
 .Nm
 never read them.
 .It Fl r , -raw
-Don't translate unprintable characters to \eooo.
-Normally
-.Nm
-translates unprintable characters to their octal representation.
+No operation, included for historical compatibility.
 .It Fl s , -special-files
 Normally,
 .Nm
@@ -325,28 +332,53 @@
 adds
 .Sq .mgc
 to the value of this variable as appropriate.
-The environment variable
-.Dv POSIXLY_CORRECT
-controls (on systems that support symbolic links), whether
-.Nm
-will attempt to follow symlinks or not. If set, then
-.Nm
-follows symlink, otherwise it does not. This is also controlled
-by the
-.Fl L
+.Sh LEGACY DESCRIPTION
+In legacy mode, the
+.Fl D ,
+.Fl I ,
+and
+.Fl M
+options do not exist.
+.Pp
+The
+.Fl d ,
+.Fl i ,
 and
+.Fl r
+options behave differently.
+The
+.Fl d
+option provides debugging information (same as
+.Fl D
+in conformance mode).
+The
+.Fl i
+option displays mime type information (same as
+.Fl I
+in conformance mode).
+The
+.Fl r
+option will disable the translation of unprintable characters (by
+default, this translation is already disabled in conformance mode).
+.Pp
+Furthermore, the
 .Fl h
-options.
+option becomes the default symlink behavior (don't follow symlinks)
+unless
+.Dv POSIXLY_CORRECT
+is set.
+.Pp
+For more information about legacy mode, see
+.Xr compat 5 .
 .Sh SEE ALSO
 .Xr magic __FSECTION__ ,
 .Xr strings 1 ,
 .Xr od 1 ,
 .Xr hexdump 1,
-.Xr file 1posix
+.Xr compat 5
 .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 behavior is mostly compatible with the System V program of the same name.
 This version knows more magic, however, so it will produce
 different (albeit more accurate) output in many cases.
@@ -466,7 +498,7 @@
 .Pp
 Altered by Chris Lowth, chris@lowth.com, 2000:
 Handle the
-.Fl i
+.Fl I
 option to output mime type strings, using an alternative
 magic file and internal logic.
 .Pp
--- src/apprentice.c.orig	2008-07-15 20:17:55.000000000 -0700
+++ src/apprentice.c	2008-07-15 21:09:02.000000000 -0700
@@ -1247,12 +1247,59 @@
 	EATAB;
 #endif
 
-	if (*l == 'u') {
+	switch (*l) {
+	case 'd':
+		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':
+		if (!isalpha((unsigned char)l[1])) {
+			m->type = FILE_STRING;
+			++l;
+		}
+		break;
+	case 'u':
 		++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;
 	}
 
-	m->type = get_type(l, &l);
+	if (!m->type) m->type = get_type(l, &l);
 	if (m->type == FILE_INVALID) {
 		if (ms->flags & MAGIC_CHECK)
 			file_magwarn(ms, "type `%s' invalid", l);
--- src/file.c.orig	2008-05-18 16:21:17.000000000 -0700
+++ src/file.c	2008-07-16 17:35:56.000000000 -0700
@@ -74,13 +74,20 @@
 
 #include "patchlevel.h"
 
+#ifdef __APPLE__
+#include "get_compat.h"
+#else
+#define COMPAT_MODE(func, mode) 1
+#endif
+
 #ifdef S_IFLNK
 #define SYMLINKFLAG "Lh"
 #else
 #define SYMLINKFLAG ""
 #endif
 
-# define USAGE  "Usage: %s [-bcik" SYMLINKFLAG "nNrsvz0] [-e test] [-f namefile] [-F separator] [-m magicfiles] file...\n       %s -C -m magicfiles\n"
+# define USAGE   "Usage: %s [-bcdik" SYMLINKFLAG "nNrsvz0] [-e test] [-f namefile] [-F separator] [-m magicfiles] file...\n       %s -C -m magicfiles\n"
+# define USAGE03 "Usage: %s [-bcdDiIk" SYMLINKFLAG "nNrsvz0] [-e test] [-f namefile] [-F separator] [-m magicfiles] [-M magicfiles] file...\n       %s -C -m magicfiles\n"
 
 #ifndef MAXPATHLEN
 #define	MAXPATHLEN	1024
@@ -100,12 +107,15 @@
     {longname, opt, NULL, shortname},
 #define OPT_LONGONLY(longname, opt, doc)        \
     {longname, opt, NULL, 0},
+#define OPT_UNIX03(shortname, doc)
 #include "file_opts.h"
 #undef OPT
 #undef OPT_LONGONLY
+#undef OPT_UNIX03
     {0, 0, NULL, 0}
 };
 #define OPTSTRING	"bcCde:f:F:hikLm:nNprsvz0"
+#define OPTSTRING03	"bcCdDe:f:F:hiIkLm:M:nNprsvz0"
 
 private const struct {
 	const char *name;
@@ -147,6 +157,9 @@
 	struct magic_set *magic = NULL;
 	char magicpath[2 * MAXPATHLEN + 2];
 	int longindex;
+	int dflag = 0; /* POSIX 'd' option -- use default magic file */
+	int Mflag = 0;
+	int unix03 = COMPAT_MODE("bin/file", "unix2003");
 	const char *magicfile;		/* where the magic is	*/
 
 	/* makes islower etc work for other langs */
@@ -177,9 +190,10 @@
 		}
 
 #ifdef S_IFLNK
-	flags |= getenv("POSIXLY_CORRECT") ? MAGIC_SYMLINK : 0;
+	flags |= (unix03 || getenv("POSIXLY_CORRECT")) ? (MAGIC_SYMLINK) : 0;
 #endif
-	while ((c = getopt_long(argc, argv, OPTSTRING, long_options,
+	if (unix03) flags |= MAGIC_RAW; /* See 5747343. */
+	while ((c = getopt_long(argc, argv, unix03 ? OPTSTRING03 : OPTSTRING, long_options,
 	    &longindex)) != -1)
 		switch (c) {
 		case 0 :
@@ -211,6 +225,11 @@
 			action = FILE_COMPILE;
 			break;
 		case 'd':
+			if (unix03) {
+				++dflag;
+				break;
+			}
+		case 'D':
 			flags |= MAGIC_DEBUG|MAGIC_CHECK;
 			break;
 		case 'e':
@@ -237,12 +256,27 @@
 			separator = optarg;
 			break;
 		case 'i':
+			if (unix03) {
+				flags |= MAGIC_REGULAR;
+				break;
+			}
+		case 'I':
 			flags |= MAGIC_MIME;
 			break;
 		case 'k':
 			flags |= MAGIC_CONTINUE;
 			break;
+		case 'M':
+			++Mflag;
 		case 'm':
+			if (magicfile != default_magicfile && magicfile != usermagic) {
+				char *newmagicfile = malloc(strlen(magicfile) + strlen(separator) + strlen(optarg) + 1);
+				strcpy(newmagicfile, magicfile);
+				strcat(newmagicfile, separator);
+				strcat(newmagicfile, optarg);
+				magicfile = newmagicfile;
+				break;
+			}
 			magicfile = optarg;
 			break;
 		case 'n':
@@ -291,6 +325,10 @@
 	if (e)
		return e;
 
+	if (Mflag && !dflag) {
+		flags |= MAGIC_NO_CHECK_ASCII;
+	}
+
 	switch(action) {
 	case FILE_CHECK:
 	case FILE_COMPILE:
@@ -475,7 +513,7 @@
 private void
 usage(void)
 {
-	(void)fprintf(stderr, USAGE, progname, progname);
+	(void)fprintf(stderr, COMPAT_MODE("bin/file", "unix2003") ? USAGE03 : USAGE, progname, progname);
 	(void)fputs("Try `file --help' for more information.\n", stderr);
 	exit(1);
 }
@@ -483,16 +521,20 @@
 private void
 help(void)
 {
+	int unix03 = COMPAT_MODE("bin/file", "unix2003");
 	(void)fputs(
 "Usage: file [OPTION...] [FILE...]\n"
 "Determine type of FILEs.\n"
 "\n", stderr);
 #define OPT(shortname, longname, opt, doc)      \
-	fprintf(stderr, "  -%c, --" longname doc, shortname);
+	fprintf(stderr, "  -%c, --" longname doc, unix03 || (shortname != 'D' && shortname != 'I') ? shortname : shortname + 32);
 #define OPT_LONGONLY(longname, opt, doc)        \
	fprintf(stderr, "      --" longname doc);
+#define OPT_UNIX03(shortname, doc)              \
+	if (unix03) fprintf(stderr, "  -%c" doc, shortname);
 #include "file_opts.h"
 #undef OPT
 #undef OPT_LONGONLY
+#undef OPT_UNIX03
 	exit(0);
 }
--- src/file_opts.h.orig	2007-11-18 12:57:57.000000000 -0800
+++ src/file_opts.h	2008-07-15 22:38:07.000000000 -0700
@@ -16,17 +16,21 @@
 OPT('v', "version", 0, "              output version information and exit\n")
 OPT('m', "magic-file", 1, " LIST      use LIST as a colon-separated list of magic\n"
     "                               number files\n")
+OPT_UNIX03('M', " LIST                    use LIST as a colon-separated list of magic\n"
+    "                               number files in place of default\n")
 OPT('z', "uncompress", 0, "           try to look inside compressed files\n")
 OPT('b', "brief", 0, "                do not prepend filenames to output lines\n")
 OPT('c', "checking-printout", 0, "    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")
+OPT_UNIX03('d', "                         use default magic file\n") 
 OPT('e', "exclude", 1, " TEST         exclude TEST from the list of test to be\n"
     "                               performed for file. Valid tests are:\n"
     "                               ascii, apptype, compress, elf, soft, tar, tokens, troff\n")
 OPT('f', "files-from", 1, " FILE      read the filenames to be examined from FILE\n")
 OPT('F', "separator", 1, " STRING     use string as separator instead of `:'\n")
-OPT('i', "mime", 0, "                 output MIME type strings (--mime-type and\n"
+OPT_UNIX03('i', "                         do not further classify regular files\n")
+OPT('I', "mime", 0, "                 output MIME type strings (--mime-type and\n"
     "                               --mime-encoding)\n")
 OPT_LONGONLY("apple", 0, "                output the Apple CREATOR/TYPE\n")
 OPT_LONGONLY("mime-type", 0, "            output the MIME type\n")
@@ -46,4 +50,5 @@
 OPT('s', "special-files", 0, "        treat special (block/char devices) files as\n"
     "                             ordinary ones\n")
 OPT('C', "compile", 0, "              compile file specified by -m\n")
-OPT('d', "debug", 0, "                print debugging messages\n")
+/* 'D' is always debug, 'd' is frequently something else */
+OPT('D', "debug", 0, "                print debugging messages\n")
--- src/fsmagic.c.orig	2008-07-15 19:17:05.000000000 -0700
+++ src/fsmagic.c	2008-07-15 19:58:19.000000000 -0700
@@ -73,7 +73,7 @@
		if (err == ELOOP)
			errfmt = "symbolic link in a loop";
		else
-			errfmt = "broken symbolic link to `%s'";
+			errfmt = "broken symbolic link to %s";
		if (ms->flags & MAGIC_ERROR) {
			file_error(ms, err, errfmt, buf);
			return -1;
@@ -126,6 +126,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);
@@ -314,7 +322,7 @@
 			if (mime) {
 				if (handle_mime(ms, mime, "x-symlink") == -1)
 					return -1;
-			} else if (file_printf(ms, "symbolic link to `%s'",
+			} else if (file_printf(ms, "symbolic link to %s",
 			    buf) == -1)
 				return -1;
 		}
@@ -332,6 +340,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);
--- src/magic.c.orig	2008-07-15 20:03:24.000000000 -0700
+++ src/magic.c	2008-07-15 20:11:49.000000000 -0700
@@ -61,6 +61,12 @@
 
 #include "patchlevel.h"
 
+#ifdef __APPLE__
+#include "get_compat.h"
+#else
+#define COMPAT_MODE(func, mode) 1
+#endif
+
 #ifndef PIPE_BUF
 /* Get the PIPE_BUF from pathconf */
 #ifdef _PC_PIPE_BUF
@@ -136,6 +142,11 @@
 unreadable_info(struct magic_set *ms, mode_t md, const char *file)
 {
 	/* We cannot open it, but we were able to stat it. */
+	if (COMPAT_MODE("bin/file", "unix2003")) {
+		if (file_printf(ms, "cannot open: %s", strerror(errno)) == -1)
+			return -1;
+		return 0;
+	}
 	if (access(file, W_OK) == 0)
 		if (file_printf(ms, "writable, ") == -1)
 			return -1;
--- src/magic.h.orig	2008-07-15 19:27:32.000000000 -0700
+++ src/magic.h	2008-07-15 20:55:20.000000000 -0700
@@ -52,6 +52,7 @@
 #define	MAGIC_NO_CHECK_CDF	0x040000 /* Don't check for cdf files */
 #define	MAGIC_NO_CHECK_TOKENS	0x100000 /* Don't check tokens */
 #define MAGIC_NO_CHECK_ENCODING 0x200000 /* Don't check text encodings */
+#define	MAGIC_REGULAR		0x400000 /* Report as regular file */
 
 /* Defined for backwards compatibility (renamed) */
 #define	MAGIC_NO_CHECK_ASCII	MAGIC_NO_CHECK_TEXT
--- src/names.h.orig	2008-07-15 18:56:34.000000000 -0700
+++ src/names.h	2008-07-15 19:00:57.000000000 -0700
@@ -60,7 +60,7 @@
 	char human[48];
 	char mime[16];
 } types[] = {
-	{ "C program",					"text/x-c", },
+	{ "c program",					"text/x-c", },
 	{ "C++ program",				"text/x-c++" },
 	{ "make commands",				"text/x-makefile" },
 	{ "PL/1 program",				"text/x-pl1" },