--- 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" },