From ace9da574a82dc9b0152e245f75230c379139ff6 Mon Sep 17 00:00:00 2001 From: Christos Zoulas Date: Thu, 25 Jan 2007 21:05:46 +0000 Subject: [PATCH] add exclude flag. centralize buffer tests. --- ChangeLog | 7 +++++++ doc/file.man | 27 +++++++++++++++++++++++++++ doc/libmagic.man | 20 ++++++++++++++++++++ src/ascmagic.c | 10 +++++++--- src/compress.c | 10 +++++----- src/file.c | 36 +++++++++++++++++++++++++++++++++--- src/file.h | 14 +++++++++----- src/funcs.c | 44 ++++++++++++++++++++++++++++++++++++++------ src/magic.c | 30 +++--------------------------- src/magic.h | 31 ++++++++++++++++++++----------- 10 files changed, 169 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6a23e815..bddbfe99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ + +2007-01-25 16:01 Christos Zoulas + + * Centralize all the tests in file_buffer. + + * Add exclude flag. + 2007-01-18 05:29 Anon Ymous * Move the "type" detection code from parse() into its own table diff --git a/doc/file.man b/doc/file.man index 1f982052..1d863a35 100644 --- a/doc/file.man +++ b/doc/file.man @@ -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 diff --git a/doc/libmagic.man b/doc/libmagic.man index 3ef560c0..0e4978b5 100644 --- a/doc/libmagic.man +++ b/doc/libmagic.man @@ -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 diff --git a/src/ascmagic.c b/src/ascmagic.c index 30df77ea..961febd4 100644 --- a/src/ascmagic.c +++ b/src/ascmagic.c @@ -49,7 +49,7 @@ #include "names.h" #ifndef lint -FILE_RCSID("@(#)$File: ascmagic.c,v 1.47 2007/01/12 17:38:27 christos Exp $") +FILE_RCSID("@(#)$File: ascmagic.c,v 1.48 2007/01/16 14:56:45 ljt 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; diff --git a/src/compress.c b/src/compress.c index 5d845963..d80a4b12 100644 --- a/src/compress.c +++ b/src/compress.c @@ -51,7 +51,7 @@ #endif #ifndef lint -FILE_RCSID("@(#)$File: compress.c,v 1.46 2007/01/12 17:38:27 christos Exp $") +FILE_RCSID("@(#)$File: compress.c,v 1.47 2007/01/16 14:56:45 ljt 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; diff --git a/src/file.c b/src/file.c index a2e77301..8a5706a1 100644 --- a/src/file.c +++ b/src/file.c @@ -71,7 +71,7 @@ #include "patchlevel.h" #ifndef lint -FILE_RCSID("@(#)$File: file.c,v 1.105 2007/01/12 17:38:28 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.106 2007/01/16 14:54:57 ljt Exp $") #endif /* lint */ @@ -81,7 +81,7 @@ FILE_RCSID("@(#)$File: file.c,v 1.105 2007/01/12 17:38:28 christos 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" diff --git a/src/file.h b/src/file.h index 0608fe88..98eb0c27 100644 --- a/src/file.h +++ b/src/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.85 2007/01/16 14:58:48 ljt Exp $ + * @(#)$File: file.h,v 1.86 2007/01/18 05:29:33 ljt 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 *); diff --git a/src/funcs.c b/src/funcs.c index 3df2193c..3246a086 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -38,7 +38,7 @@ #endif #ifndef lint -FILE_RCSID("@(#)$File: funcs.c,v 1.24 2007/01/12 17:38:28 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.25 2007/01/16 14:58:48 ljt 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 diff --git a/src/magic.c b/src/magic.c index 556b7153..e9c86625 100644 --- a/src/magic.c +++ b/src/magic.c @@ -63,7 +63,7 @@ #include "patchlevel.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.36 2007/01/12 17:38:28 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.37 2007/01/16 14:58:48 ljt 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); diff --git a/src/magic.h b/src/magic.h index 869f9ea2..39fa2e11 100644 --- a/src/magic.h +++ b/src/magic.h @@ -29,17 +29,26 @@ #include -#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" { -- 2.40.0