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;