]> granicus.if.org Git - file/commitdiff
add exclude flag. centralize buffer tests.
authorChristos Zoulas <christos@zoulas.com>
Thu, 25 Jan 2007 21:05:46 +0000 (21:05 +0000)
committerChristos Zoulas <christos@zoulas.com>
Thu, 25 Jan 2007 21:05:46 +0000 (21:05 +0000)
ChangeLog
doc/file.man
doc/libmagic.man
src/ascmagic.c
src/compress.c
src/file.c
src/file.h
src/funcs.c
src/magic.c
src/magic.h

index 6a23e8152d94c85915092d76a6a3fa041c226ea1..bddbfe99567772ca60d37d100c4b65854d9c79a6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+
+2007-01-25 16:01 Christos Zoulas <christos@zoulas.com>
+
+       * Centralize all the tests in file_buffer.
+
+       * Add exclude flag.
+
 2007-01-18 05:29 Anon Ymous <do@not.spam.me>
        
        * Move the "type" detection code from parse() into its own table
index c66f6acdc1f11599718d1f792f603d07aa6ddb10..f0961043b0e3f0bb8f337e12237b4ce82e7eb5af 100644 (file)
@@ -1,4 +1,4 @@
-.\" $File: file.man,v 1.64 2007/01/12 17:38:27 christos Exp $
+.\" $File: file.man,v 1.65 2007/01/25 21:05:46 christos Exp $
 .Dd January 8, 2007
 .Dt FILE __CSECTION__
 .Os
@@ -175,6 +175,33 @@ flag to debug a new magic file before installing it.
 Write a
 .Pa magic.mgc
 output file that contains a pre-parsed version of the magic file.
+.It Fl e , -exclude Ar testname
+Exclude the test named in
+.Ar testname
+from the list of tests made to determine the file type. Valid test names
+are:
+.Bl -tag -width
+.It apptype
+Check for
+.Dv EMX
+application type (only on EMX).
+.It ascii
+Check for various types of ascii files.
+.It compress
+Don't look for, or inside compressed files.
+.It elf
+Don't print elf details.
+.It fortran
+Don't look for fortran sequences inside ascii files.
+.It soft
+Don't consult magic files.
+.It tar
+Don't examine tar files.
+.It token
+Don't look for known tokens inside ascii files.
+.It troff
+Don't look for troff sequences inside ascii files.
+.El
 .It Fl f , -files-from Ar namefile
 Read the names of the files to be examined from 
 .Ar namefile
index 3ef560c0f9e76e2cffecab0e894ad540384fe907..0e4978b5d8e0479cbdc02280d490f6113d67e54c 100644 (file)
@@ -104,6 +104,26 @@ Don't translate unprintable characters to a \eooo octal representation.
 .It Dv MAGIC_ERROR
 Treat operating system errors while trying to open files and follow symlinks
 as real errors, instead of printing them in the magic buffer.
+.It Dv MAGIC_NO_CHECK_APPTYPE
+Check for
+.Dv EMX
+application type (only on EMX).
+.It Dv MAGIC_NO_CHECK_ASCII
+Check for various types of ascii files.
+.It Dv MAGIC_NO_CHECK_COMPRESS
+Don't look for, or inside compressed files.
+.It Dv MAGIC_NO_CHECK_ELF
+Don't print elf details.
+.It Dv MAGIC_NO_CHECK_FORTRAN
+Don't look for fortran sequences inside ascii files.
+.It Dv MAGIC_NO_CHECK_SOFT
+Don't consult magic files.
+.It Dv MAGIC_NO_CHECK_TAR
+Don't examine tar files.
+.It Dv MAGIC_NO_CHECK_TOKENS
+Don't look for known tokens inside ascii files.
+.It Dv MAGIC_NO_CHECK_TROFF
+Don't look for troff sequences inside ascii files.
 .El
 .Pp
 The
index 301b273482d2670061065090b9222cfc4de37310..771eda3cba5ce8bfa5a818f579841bb689c197da 100644 (file)
@@ -49,7 +49,7 @@
 #include "names.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: ascmagic.c,v 1.48 2007/01/16 14:56:45 ljt Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.49 2007/01/25 21:05:46 christos Exp $")
 #endif /* lint */
 
 typedef unsigned long unichar;
@@ -167,7 +167,7 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
         * I believe Plan 9 troff allows non-ASCII characters in the names
         * of macros, so this test might possibly fail on such a file.
         */
-       if (*ubuf == '.') {
+       if ((ms->flags & MAGIC_NO_CHECK_TROFF) != 0 && *ubuf == '.') {
                unichar *tp = ubuf + 1;
 
                while (ISSPC(*tp))
@@ -184,7 +184,8 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
                }
        }
 
-       if ((*buf == 'c' || *buf == 'C') && ISSPC(buf[1])) {
+       if ((ms->flags & MAGIC_NO_CHECK_FORTRAN) &&
+           (*buf == 'c' || *buf == 'C') && ISSPC(buf[1])) {
                subtype_mime = "text/fortran";
                subtype = "fortran program";
                goto subtype_identified;
@@ -192,6 +193,9 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
 
        /* look for tokens from names.h - this is expensive! */
 
+       if ((ms->flags & MAGIC_NO_CHECK_TOKENS) != 0)
+               goto subtype_identified;
+
        i = 0;
        while (i < ulen) {
                size_t end;
index ca9064dc1a145d5677e62320e2a414cd295535fe..7262de14c471ddb7bf3dac2c4057d0d742233678 100644 (file)
@@ -51,7 +51,7 @@
 #endif
 
 #ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.47 2007/01/16 14:56:45 ljt Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.48 2007/01/25 21:05:46 christos Exp $")
 #endif
 
 private struct {
@@ -88,8 +88,8 @@ private size_t uncompressgzipped(struct magic_set *, const unsigned char *,
 #endif
 
 protected int
-file_zmagic(struct magic_set *ms, int fd, const unsigned char *buf,
-    size_t nbytes)
+file_zmagic(struct magic_set *ms, int fd, const char *name,
+    const unsigned char *buf, size_t nbytes)
 {
        unsigned char *newbuf = NULL;
        size_t i, nsz;
@@ -106,11 +106,11 @@ file_zmagic(struct magic_set *ms, int fd, const unsigned char *buf,
                    nbytes)) != NODATA) {
                        ms->flags &= ~MAGIC_COMPRESS;
                        rv = -1;
-                       if (file_buffer(ms, -1, newbuf, nsz) == -1)
+                       if (file_buffer(ms, -1, name, newbuf, nsz) == -1)
                                goto error;
                        if (file_printf(ms, " (") == -1)
                                goto error;
-                       if (file_buffer(ms, -1, buf, nbytes) == -1)
+                       if (file_buffer(ms, -1, NULL, buf, nbytes) == -1)
                                goto error;
                        if (file_printf(ms, ")") == -1)
                                goto error;
index f54cdc42031f5b4bf5f003774d2bf7cef7ea7828..35d512ae4a59a303b43f2ddf9c46923ad05a95b1 100644 (file)
@@ -71,7 +71,7 @@
 #include "patchlevel.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: file.c,v 1.106 2007/01/16 14:54:57 ljt Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.107 2007/01/25 21:05:46 christos Exp $")
 #endif /* lint */
 
 
@@ -81,7 +81,7 @@ FILE_RCSID("@(#)$File: file.c,v 1.106 2007/01/16 14:54:57 ljt Exp $")
 #define SYMLINKFLAG ""
 #endif
 
-# define USAGE  "Usage: %s [-bcik" SYMLINKFLAG "nNrsvz0] [-f namefile] [-F separator] [-m magicfiles] file...\n       %s -C -m magicfiles\n"
+# define USAGE  "Usage: %s [-bcik" SYMLINKFLAG "nNrsvz0] [-e test] [-f namefile] [-F separator] [-m magicfiles] file...\n       %s -C -m magicfiles\n"
 
 #ifndef MAXPATHLEN
 #define        MAXPATHLEN      512
@@ -122,7 +122,7 @@ private void load(const char *, int);
 int
 main(int argc, char *argv[])
 {
-       int c;
+       int c, i;
        int action = 0, didsomefiles = 0, errflg = 0;
        int flags = 0;
        char *home, *usermagic;
@@ -138,6 +138,7 @@ main(int argc, char *argv[])
                {"brief", 0, 0, 'b'},
                {"checking-printout", 0, 0, 'c'},
                {"debug", 0, 0, 'd'},
+               {"exclude", 0, 0, 'e' },
                {"files-from", 1, 0, 'f'},
                {"separator", 1, 0, 'F'},
                {"mime", 0, 0, 'i'},
@@ -161,6 +162,21 @@ main(int argc, char *argv[])
        };
 #endif
 
+       static const struct {
+               const char *name;
+               int value;
+       } nv[] = {
+               { "apptype",    MAGIC_NO_CHECK_APPTYPE },
+               { "ascii",      MAGIC_NO_CHECK_ASCII },
+               { "compress",   MAGIC_NO_CHECK_COMPRESS },
+               { "elf",        MAGIC_NO_CHECK_ELF },
+               { "fortran",    MAGIC_NO_CHECK_FORTRAN },
+               { "soft",       MAGIC_NO_CHECK_SOFT },
+               { "tar",        MAGIC_NO_CHECK_TAR },
+               { "tokens",     MAGIC_NO_CHECK_TOKENS },
+               { "troff",      MAGIC_NO_CHECK_TROFF },
+       };
+
 #ifdef LC_CTYPE
        /* makes islower etc work for other langs */
        (void)setlocale(LC_CTYPE, "");
@@ -223,6 +239,17 @@ main(int argc, char *argv[])
                case 'd':
                        flags |= MAGIC_DEBUG|MAGIC_CHECK;
                        break;
+               case 'e':
+                       for (i = 0; i < sizeof(nv) / sizeof(nv[0]); i++)
+                               if (strcmp(nv[i].name, optarg) == 0)
+                                       break;
+
+                       if (i == sizeof(nv) / sizeof(nv[0]))
+                               errflg++;
+                       else
+                               flags |= nv[i].value;
+                       break;
+                       
                case 'f':
                        if(action)
                                usage();
@@ -535,6 +562,9 @@ help(void)
 "  -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"
+"  -e, --exclude              exclude test from the list of test to be\n"
+"                               performed for file. Valid tests are:\n"
+"                               ascii, apptype, elf, compress, soft, tar\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"
index 50912ba8b4566d59943088b9dec68b5c40f03b90..59130831e843be931ac81b73cbb512a0e4b56b5f 100644 (file)
@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.86 2007/01/18 05:29:33 ljt Exp $
+ * @(#)$File: file.h,v 1.87 2007/01/25 21:05:47 christos Exp $
  */
 
 #ifndef __file_h__
@@ -304,18 +304,22 @@ struct magic_set {
 
 struct stat;
 protected const char *file_fmttime(uint32_t, int);
-protected int file_buffer(struct magic_set *, int, const void *, size_t);
+protected int file_buffer(struct magic_set *, int, const char *, const void *,
+    size_t);
 protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
 protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
 protected int file_printf(struct magic_set *, const char *, ...);
 protected int file_reset(struct magic_set *);
-protected int file_tryelf(struct magic_set *, int, const unsigned char *, size_t);
-protected int file_zmagic(struct magic_set *, int, const unsigned char *, size_t);
+protected int file_tryelf(struct magic_set *, int, const unsigned char *,
+    size_t);
+protected int file_zmagic(struct magic_set *, int, const char *,
+    const unsigned char *, size_t);
 protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t);
 protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
 protected int file_softmagic(struct magic_set *, const unsigned char *, size_t);
 protected struct mlist *file_apprentice(struct magic_set *, const char *, int);
-protected uint64_t file_signextend(struct magic_set *, struct magic *, uint64_t);
+protected uint64_t file_signextend(struct magic_set *, struct magic *,
+    uint64_t);
 protected void file_delmagic(struct magic *, int type, size_t entries);
 protected void file_badread(struct magic_set *);
 protected void file_badseek(struct magic_set *);
index c3721dcc00280f101aed5d5e4eb548788536c630..4417b602997b904069d4d148a523e186364e1b7d 100644 (file)
@@ -38,7 +38,7 @@
 #endif
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.25 2007/01/16 14:58:48 ljt Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.26 2007/01/25 21:05:47 christos Exp $")
 #endif /* lint */
 
 #ifndef HAVE_VSNPRINTF
@@ -147,17 +147,36 @@ file_badread(struct magic_set *ms)
 
 #ifndef COMPILE_ONLY
 protected int
-file_buffer(struct magic_set *ms, int fd, const void *buf, size_t nb)
+file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
+    size_t nb)
 {
     int m;
+
+#ifdef __EMX__
+    if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
+       switch (file_os2_apptype(ms, inname, buf, nb)) {
+       case -1:
+           return -1;
+       case 0:
+           break;
+       default:
+           return 1;
+       }
+    }
+#endif
+
     /* try compression stuff */
-    if ((m = file_zmagic(ms, fd, buf, nb)) == 0) {
+    if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0 ||
+        (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) {
        /* Check if we have a tar file */
-       if ((m = file_is_tar(ms, buf, nb)) == 0) {
+       if ((ms->flags & MAGIC_NO_CHECK_TAR) == 0 ||
+           (m = file_is_tar(ms, buf, nb)) == 0) {
            /* try tests in /etc/magic (or surrogate magic file) */
-           if ((m = file_softmagic(ms, buf, nb)) == 0) {
+           if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0 ||
+               (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_NO_CHECK_ASCII) == 0 ||
+                   (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" :
@@ -170,6 +189,19 @@ file_buffer(struct magic_set *ms, int fd, const void *buf, size_t nb)
            }
        }
     }
+#ifdef BUILTIN_ELF
+    if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && nb > 5 && fd != -1) {
+       /*
+        * We matched something in the file, so this *might*
+        * be an ELF file, and the file is at least 5 bytes
+        * long, so if it's an ELF file it has at least one
+        * byte past the ELF magic number - try extracting
+        * information from the ELF headers that cannot easily
+        * be extracted with rules in the magic file.
+        */
+       (void)file_tryelf(ms, fd, buf, nb);
+    }
+#endif
     return m;
 }
 #endif
index be0253982167d1b23febf700143021ab9b77bacc..26ef17d8565082bcd735881fd9af67ffaaaefba6 100644 (file)
@@ -63,7 +63,7 @@
 #include "patchlevel.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: magic.c,v 1.37 2007/01/16 14:58:48 ljt Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.38 2007/01/25 21:05:47 christos Exp $")
 #endif /* lint */
 
 #ifdef __EMX__
@@ -334,32 +334,8 @@ magic_file(struct magic_set *ms, const char *inname)
                        goto done;
        } else {
                (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
-#ifdef __EMX__
-               switch (file_os2_apptype(ms, inname, buf, nbytes)) {
-               case -1:
-                       goto done;
-               case 0:
-                       break;
-               default:
-                       rv = 0;
-                       goto done;
-               }
-#endif
-               if (file_buffer(ms, fd, buf, (size_t)nbytes) == -1)
+               if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
                        goto done;
-#ifdef BUILTIN_ELF
-               if (nbytes > 5) {
-                       /*
-                        * We matched something in the file, so this *might*
-                        * be an ELF file, and the file is at least 5 bytes
-                        * long, so if it's an ELF file it has at least one
-                        * byte past the ELF magic number - try extracting
-                        * information from the ELF headers that cannot easily
-                        * be extracted with rules in the magic file.
-                        */
-                       (void) file_tryelf(ms, fd, buf, (size_t)nbytes);
-               }
-#endif
        }
        rv = 0;
 done:
@@ -378,7 +354,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
         * The main work is done here!
         * We have the file name and/or the data buffer to be identified. 
         */
-       if (file_buffer(ms, -1, buf, nb) == -1) {
+       if (file_buffer(ms, -1, NULL, buf, nb) == -1) {
                return NULL;
        }
        return file_getbuffer(ms);
index 869f9ea28d688dac23a274820ea3d8894ebad4d8..39fa2e11f91909a9b87746a3fc5b1a31382a276a 100644 (file)
 
 #include <sys/types.h>
 
-#define        MAGIC_NONE              0x000   /* No flags */
-#define        MAGIC_DEBUG             0x001   /* Turn on debugging */
-#define        MAGIC_SYMLINK           0x002   /* Follow symlinks */
-#define        MAGIC_COMPRESS          0x004   /* Check inside compressed files */
-#define        MAGIC_DEVICES           0x008   /* Look at the contents of devices */
-#define        MAGIC_MIME              0x010   /* Return a mime string */
-#define        MAGIC_CONTINUE          0x020   /* Return all matches */
-#define        MAGIC_CHECK             0x040   /* Print warnings to stderr */
-#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_NONE              0x000000 /* No flags */
+#define        MAGIC_DEBUG             0x000001 /* Turn on debugging */
+#define        MAGIC_SYMLINK           0x000002 /* Follow symlinks */
+#define        MAGIC_COMPRESS          0x000004 /* Check inside compressed files */
+#define        MAGIC_DEVICES           0x000008 /* Look at the contents of devices */
+#define        MAGIC_MIME              0x000010 /* Return a mime string */
+#define        MAGIC_CONTINUE          0x000020 /* Return all matches */
+#define        MAGIC_CHECK             0x000040 /* Print warnings to stderr */
+#define        MAGIC_PRESERVE_ATIME    0x000080 /* Restore access time on exit */
+#define        MAGIC_RAW               0x000100 /* Don't translate unprintable chars */
+#define        MAGIC_ERROR             0x000200 /* Handle ENOENT etc as real errors */
+#define MAGIC_NO_CHECK_COMPRESS        0x001000 /* Don't check for compressed files */
+#define MAGIC_NO_CHECK_TAR     0x002000 /* Don't check for tar files */
+#define MAGIC_NO_CHECK_SOFT    0x004000 /* Don't check magic entries */
+#define MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */
+#define MAGIC_NO_CHECK_ELF     0x010000 /* Don't check for elf details */
+#define MAGIC_NO_CHECK_ASCII   0x020000 /* Don't check for ascii files */
+#define MAGIC_NO_CHECK_TROFF   0x040000 /* Don't check ascii/troff */
+#define MAGIC_NO_CHECK_FORTRAN 0x080000 /* Don't check ascii/fortran */
+#define MAGIC_NO_CHECK_TOKENS  0x100000 /* Don't check ascii/tokens */
 
 #ifdef __cplusplus
 extern "C" {