From: Christos Zoulas Date: Sun, 11 Mar 2001 20:29:15 +0000 (+0000) Subject: add compiled format X-Git-Tag: FILE3_34~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=62109261b63517d7573c0a8c0fd2a8ebd6a78b8e;p=file add compiled format --- diff --git a/Makefile.am b/Makefile.am index 85c09bed..9cce906f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ bin_PROGRAMS = file data_DATA = magic magic.mime MAGIC = @datadir@/magic -CPPFLAGS = -DMAGIC='"$(MAGIC)"' +CPPFLAGS = -DMAGIC='"$(MAGIC)"' -DQUICK man_MANS = file.1 magic.4 diff --git a/Makefile.in b/Makefile.in index 72bc94d0..47c15915 100644 --- a/Makefile.in +++ b/Makefile.in @@ -72,7 +72,7 @@ bin_PROGRAMS = file data_DATA = magic magic.mime MAGIC = @datadir@/magic -CPPFLAGS = -DMAGIC='"$(MAGIC)"' +CPPFLAGS = -DMAGIC='"$(MAGIC)"' -DQUICK man_MANS = file.1 magic.4 diff --git a/src/apprentice.c b/src/apprentice.c index 1c4664b5..f9225e7f 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -30,10 +30,15 @@ #include #include #include +#ifdef QUICK +#include +#include +#include +#endif #include "file.h" #ifndef lint -FILE_RCSID("@(#)$Id: apprentice.c,v 1.33 2000/08/05 17:36:47 christos Exp $") +FILE_RCSID("@(#)$Id: apprentice.c,v 1.34 2001/03/11 20:29:16 christos Exp $") #endif /* lint */ #define EATAB {while (isascii((unsigned char) *l) && \ @@ -52,27 +57,94 @@ FILE_RCSID("@(#)$Id: apprentice.c,v 1.33 2000/08/05 17:36:47 christos Exp $") static int getvalue __P((struct magic *, char **)); static int hextoint __P((int)); static char *getstr __P((char *, char *, int, int *)); -static int parse __P((char *, int *, int)); +static int parse __P((struct magic **, uint32 *, char *, int)); static void eatsize __P((char **)); +static int apprentice_1 __P((const char *, int)); +static int apprentice_file __P((struct magic **, uint32 *, + const char *, int)); +#ifdef QUICK +static void byteswap __P((struct magic *, uint32)); +static void bs1 __P((struct magic *)); +static uint16 swap2 __P((uint16)); +static uint32 swap4 __P((uint32)); +static char * mkdbname __P((const char *)); +static int apprentice_map __P((struct magic **, uint32 *, + const char *, int)); +static int apprentice_compile __P((struct magic **, uint32 *, + const char *, int)); +#endif static int maxmagic = 0; -static int apprentice_1 __P((const char *, int)); +struct mlist mlist; + + +/* + * Handle one file. + */ +static int +apprentice_1(fn, action) + const char *fn; + int action; +{ + struct magic *magic = NULL; + uint32 nmagic = 0; + struct mlist *ml; + int rv = -1; + +#ifdef QUICK + if (action == COMPILE) { + rv = apprentice_file(&magic, &nmagic, fn, action); + if (rv == 0) + return apprentice_compile(&magic, &nmagic, fn, action); + else + return rv; + } + if ((rv = apprentice_map(&magic, &nmagic, fn, action)) != 0) + (void)fprintf(stderr, "%s: Using regular magic file `%s'\n", + progname, fn); +#endif + + if (rv != 0) + rv = apprentice_file(&magic, &nmagic, fn, action); + + if (rv != 0) + return rv; + + if ((ml = malloc(sizeof(*ml))) == NULL) { + (void) fprintf(stderr, "%s: Out of memory.\n", progname); + if (action == CHECK) + return -1; + } + + if (magic == NULL || nmagic == 0) + return rv; + + ml->magic = magic; + ml->nmagic = nmagic; + + mlist.prev->next = ml; + ml->prev = mlist.prev; + ml->next = &mlist; + mlist.prev = ml; + + return rv; +} + int -apprentice(fn, check) +apprentice(fn, action) const char *fn; /* list of magic files */ - int check; /* non-zero? checking-only run. */ + int action; { char *p, *mfn; int file_err, errs = -1; - maxmagic = MAXMAGIS; - magic = (struct magic *) calloc(sizeof(struct magic), maxmagic); + mlist.next = mlist.prev = &mlist; mfn = malloc(strlen(fn)+1); - if (magic == NULL || mfn == NULL) { + if (mfn == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); - if (check) + if (action == CHECK) return -1; else exit(1); @@ -83,25 +155,30 @@ apprentice(fn, check) p = strchr(fn, PATHSEP); if (p) *p++ = '\0'; - file_err = apprentice_1(fn, check); + file_err = apprentice_1(fn, action); if (file_err > errs) errs = file_err; fn = p; } if (errs == -1) (void) fprintf(stderr, "%s: couldn't find any magic files!\n", - progname); - if (!check && errs) + progname); + if (action == CHECK && errs) exit(1); free(mfn); return errs; } +/* + * parse from a file + */ static int -apprentice_1(fn, check) +apprentice_file(magicp, nmagicp, fn, action) + struct magic **magicp; + uint32 *nmagicp; const char *fn; /* name of magic file */ - int check; /* non-zero? checking-only run. */ + int action; { static const char hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"; @@ -110,7 +187,7 @@ apprentice_1(fn, check) int errs = 0; f = fopen(fn, "r"); - if (f==NULL) { + if (f == NULL) { if (errno != ENOENT) (void) fprintf(stderr, "%s: can't read magic file %s (%s)\n", @@ -118,8 +195,16 @@ apprentice_1(fn, check) return -1; } + maxmagic = MAXMAGIS; + *magicp = (struct magic *) calloc(sizeof(struct magic), maxmagic); + if (*magicp == NULL) { + (void) fprintf(stderr, "%s: Out of memory.\n", progname); + if (action == CHECK) + return -1; + } + /* parse it */ - if (check) /* print silly verbose header for USG compat. */ + if (action == CHECK) /* print silly verbose header for USG compat. */ (void) printf("%s\n", hdr); for (lineno = 1;fgets(line, BUFSIZ, f) != NULL; lineno++) { @@ -128,11 +213,16 @@ apprentice_1(fn, check) if (strlen(line) <= (unsigned)1) /* null line, garbage, etc */ continue; line[strlen(line)-1] = '\0'; /* delete newline */ - if (parse(line, &nmagic, check) != 0) + if (parse(magicp, nmagicp, line, action) != 0) errs = 1; } (void) fclose(f); + if (errs) { + free(*magicp); + *magicp = NULL; + *nmagicp = 0; + } return errs; } @@ -181,32 +271,35 @@ signextend(m, v) * parse one line from magic file, put into magic[index++] if valid */ static int -parse(l, ndx, check) +parse(magicp, nmagicp, l, action) + struct magic **magicp; + uint32 *nmagicp; char *l; - int *ndx, check; + int action; { - int i = 0, nd = *ndx; + int i = 0; struct magic *m; char *t, *s; #define ALLOC_INCR 200 - if (nd+1 >= maxmagic){ + if (*nmagicp + 1 >= maxmagic){ maxmagic += ALLOC_INCR; - if ((m = (struct magic *) realloc(magic, sizeof(struct magic) * - maxmagic)) == NULL) { + if ((m = (struct magic *) realloc(*magicp, + sizeof(struct magic) * maxmagic)) == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); - if (magic) - free(magic); - if (check) + if (*magicp) + free(*magicp); + if (action == CHECK) return -1; else exit(1); } - magic = m; - memset(&magic[*ndx], 0, sizeof(struct magic) * ALLOC_INCR); + *magicp = m; + memset(&(*magicp)[*nmagicp], 0, sizeof(struct magic) + * ALLOC_INCR); } - m = &magic[*ndx]; + m = &(*magicp)[*nmagicp]; m->flag = 0; m->cont_level = 0; @@ -231,8 +324,8 @@ parse(l, ndx, check) l = t; if (m->flag & INDIR) { - m->in.type = LONG; - m->in.offset = 0; + m->in_type = LONG; + m->in_offset = 0; /* * read [.lbs][+-]nnnnn) */ @@ -240,24 +333,24 @@ parse(l, ndx, check) l++; switch (*l) { case 'l': - m->in.type = LELONG; + m->in_type = LELONG; break; case 'L': - m->in.type = BELONG; + m->in_type = BELONG; break; case 'h': case 's': - m->in.type = LESHORT; + m->in_type = LESHORT; break; case 'H': case 'S': - m->in.type = BESHORT; + m->in_type = BESHORT; break; case 'c': case 'b': case 'C': case 'B': - m->in.type = BYTE; + m->in_type = BYTE; break; default: magwarn("indirect offset type %c invalid", *l); @@ -268,8 +361,8 @@ parse(l, ndx, check) s = l; if (*l == '+' || *l == '-') l++; if (isdigit((unsigned char)*l)) { - m->in.offset = strtoul(l, &t, 0); - if (*s == '-') m->in.offset = - m->in.offset; + m->in_offset = strtoul(l, &t, 0); + if (*s == '-') m->in_offset = - m->in_offset; } else t = l; @@ -430,10 +523,10 @@ GetDesc: while ((m->desc[i++] = *l++) != '\0' && icont_level = swap2(m->cont_level); + m->offset = swap4(m->offset); + m->in_offset = swap4(m->in_offset); + if (m->type != STRING) + m->value.l = swap4(m->value.l); + m->mask = swap4(m->mask); +} +#endif diff --git a/src/file.c b/src/file.c index ac770d1d..429e53a6 100644 --- a/src/file.c +++ b/src/file.c @@ -56,7 +56,7 @@ #include "patchlevel.h" #ifndef lint -FILE_RCSID("@(#)$Id: file.c,v 1.55 2000/08/05 19:00:12 christos Exp $") +FILE_RCSID("@(#)$Id: file.c,v 1.56 2001/03/11 20:29:16 christos Exp $") #endif /* lint */ @@ -97,6 +97,7 @@ int lineno; /* line number in the magic file */ static void unwrap __P((char *fn)); +static void usage __P((void)); #if 0 static int byteconv4 __P((int, int, int)); static short byteconv2 __P((int, int, int)); @@ -113,7 +114,7 @@ main(argc, argv) char *argv[]; { int c; - int check = 0, didsomefiles = 0, errflg = 0, ret = 0, app = 0; + int action = 0, didsomefiles = 0, errflg = 0, ret = 0, app = 0; char *mime; #ifdef LC_CTYPE @@ -128,21 +129,24 @@ main(argc, argv) if (!(magicfile = getenv("MAGIC"))) magicfile = default_magicfile; - while ((c = getopt(argc, argv, "bcdf:ikm:nsvzL")) != EOF) + while ((c = getopt(argc, argv, "bcdf:ikm:nsvzCL")) != EOF) switch (c) { case 'b': ++bflag; break; case 'c': - ++check; + action = CHECK; + break; + case 'C': + action = COMPILE; break; case 'd': ++debug; break; case 'f': if (!app) { - ret = apprentice(magicfile, check); - if (check) + ret = apprentice(magicfile, action); + if (action) exit(ret); app = 1; } @@ -190,21 +194,19 @@ main(argc, argv) } if (errflg) { - (void) fprintf(stderr, USAGE, progname); - exit(2); + usage(); } if (!app) { - ret = apprentice(magicfile, check); - if (check) + ret = apprentice(magicfile, action); + if (action) exit(ret); app = 1; } if (optind == argc) { if (!didsomefiles) { - (void)fprintf(stderr, USAGE, progname); - exit(2); + usage(); } } else { @@ -451,3 +453,13 @@ tryit(buf, nb, zflag) ckfputs("data", stdout); return '\0'; } + +static void +usage() +{ + (void)fprintf(stderr, USAGE, progname); +#ifdef QUICK + (void)fprintf(stderr, "Usage: %s -C [-m magic]\n", progname); +#endif + exit(1); +} diff --git a/src/file.h b/src/file.h index c8ed4031..67c86d0c 100644 --- a/src/file.h +++ b/src/file.h @@ -1,6 +1,6 @@ /* * file.h - definitions for file(1) program - * @(#)$Id: file.h,v 1.34 2000/11/13 00:30:49 christos Exp $ + * @(#)$Id: file.h,v 1.35 2001/03/11 20:29:16 christos Exp $ * * Copyright (c) Ian F. Darwin, 1987. * Written by Ian F. Darwin. @@ -35,6 +35,10 @@ typedef int int32; typedef unsigned int uint32; +typedef short int16; +typedef unsigned short uint16; +typedef char int8; +typedef unsigned char uint8; #ifndef HOWMANY # define HOWMANY 16384 /* how much of the file to look at */ @@ -43,20 +47,23 @@ typedef unsigned int uint32; #define MAXDESC 50 /* max leng of text description */ #define MAXstring 32 /* max leng of "string" types */ +#define MAGICNO 0xF11E041C +#define VERSIONNO 1 + +#define CHECK 1 +#define COMPILE 2 + struct magic { - short flag; + uint16 cont_level;/* level of ">" */ + uint8 nospflag; /* supress space character */ + uint8 flag; #define INDIR 1 /* if '>(...)' appears, */ #define UNSIGNED 2 /* comparison is unsigned */ #define ADD 4 /* if '>&' appears, */ - short cont_level; /* level of ">" */ - struct { - unsigned char type; /* byte short long */ - int32 offset; /* offset from indirection */ - } in; - int32 offset; /* offset to magic number */ - unsigned char reln; /* relation (0=eq, '>'=gt, etc) */ - unsigned char type; /* int, short, long or string. */ - char vallen; /* length of string value, if any */ + uint8 reln; /* relation (0=eq, '>'=gt, etc) */ + uint8 vallen; /* length of string value, if any */ + uint8 type; /* int, short, long or string. */ + uint8 in_type; /* type of indirrection */ #define BYTE 1 #define SHORT 2 #define LONG 4 @@ -68,16 +75,17 @@ struct magic { #define LESHORT 10 #define LELONG 11 #define LEDATE 12 + int32 offset; /* offset to magic number */ + int32 in_offset; /* offset from indirection */ union VALUETYPE { unsigned char b; unsigned short h; uint32 l; char s[MAXstring]; unsigned char hs[2]; /* 2 bytes of a fixed-endian "short" */ - unsigned char hl[4]; /* 2 bytes of a fixed-endian "long" */ + unsigned char hl[4]; /* 4 bytes of a fixed-endian "long" */ } value; /* either number or string */ uint32 mask; /* mask before comparison with value */ - char nospflag; /* supress space character */ char desc[MAXDESC]; /* description */ }; @@ -90,6 +98,13 @@ struct magic { #define CHAR_COMPACT_OPTIONAL_BLANK 'b' +/* list of magic entries */ +struct mlist { + struct magic *magic; /* array of magic entries */ + uint32 nmagic; /* number of entries in array */ + struct mlist *next, *prev; +}; + #include /* Include that here, to make sure __P gets defined */ #include @@ -125,9 +140,7 @@ extern char *progname; /* the program name */ extern const char *magicfile; /* name of the magic file */ extern int lineno; /* current line number in magic file */ -extern struct magic *magic; /* array of magic entries */ -extern int nmagic; /* number of valid magic[]s */ - +extern struct mlist mlist; /* list of arrays of magic entries */ extern int debug; /* enable debugging? */ extern int zflag; /* process compressed files? */ diff --git a/src/print.c b/src/print.c index 7992f5c5..d6ae6e61 100644 --- a/src/print.c +++ b/src/print.c @@ -41,7 +41,7 @@ #include #ifndef lint -FILE_RCSID("@(#)$Id: print.c,v 1.31 2000/08/05 17:36:49 christos Exp $") +FILE_RCSID("@(#)$Id: print.c,v 1.32 2001/03/11 20:29:16 christos Exp $") #endif /* lint */ #define SZOF(a) (sizeof(a) / sizeof(a[0])) @@ -61,9 +61,9 @@ mdump(m) if (m->flag & INDIR) (void) fprintf(stderr, "(%s,%d),", /* Note: in.type is unsigned */ - (m->in.type < SZOF(typ)) ? - typ[m->in.type] : "*bad*", - m->in.offset); + (m->in_type < SZOF(typ)) ? + typ[m->in_type] : "*bad*", + m->in_offset); (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "", /* Note: type is unsigned */ diff --git a/src/softmagic.c b/src/softmagic.c index 2fb4c4a5..e954b2ee 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -35,10 +35,10 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$Id: softmagic.c,v 1.42 2000/08/05 17:36:49 christos Exp $") +FILE_RCSID("@(#)$Id: softmagic.c,v 1.43 2001/03/11 20:29:16 christos Exp $") #endif /* lint */ -static int match __P((unsigned char *, int)); +static int match __P((struct magic *, uint32, unsigned char *, int)); static int mget __P((union VALUETYPE *, unsigned char *, struct magic *, int)); static int mcheck __P((union VALUETYPE *, struct magic *)); @@ -57,8 +57,11 @@ softmagic(buf, nbytes) unsigned char *buf; int nbytes; { - if (match(buf, nbytes)) - return 1; + struct mlist *ml; + + for (ml = mlist.next; ml != &mlist; ml = ml->next) + if (match(ml->magic, ml->nmagic, buf, nbytes)) + return 1; return 0; } @@ -91,7 +94,9 @@ softmagic(buf, nbytes) * so that higher-level continuations are processed. */ static int -match(s, nbytes) +match(magic, nmagic, s, nbytes) + struct magic *magic; + uint32 nmagic; unsigned char *s; int nbytes; { @@ -105,6 +110,7 @@ match(s, nbytes) int returnval = 0; /* if a match is found it is set to 1*/ extern int kflag; int firstline = 1; /* a flag to print X\n X\n- X */ + struct mlist *ml; if (tmpoff == NULL) if ((tmpoff = (int32 *) malloc(tmplen = 20)) == NULL) @@ -153,7 +159,8 @@ match(s, nbytes) } if (magic[magindex].flag & ADD) { oldoff=magic[magindex].offset; - magic[magindex].offset += tmpoff[cont_level-1]; + magic[magindex].offset += + tmpoff[cont_level-1]; } if (mget(&p, s, &magic[magindex], nbytes) && mcheck(&p, &magic[magindex])) { @@ -172,7 +179,8 @@ match(s, nbytes) (void) putchar(' '); need_separator = 0; } - tmpoff[cont_level] = mprint(&p, &magic[magindex]); + tmpoff[cont_level] = + mprint(&p, &magic[magindex]); if (magic[magindex].desc[0]) need_separator = 1; @@ -361,33 +369,33 @@ mget(p, s, m, nbytes) if (m->flag & INDIR) { - switch (m->in.type) { + switch (m->in_type) { case BYTE: - offset = p->b + m->in.offset; + offset = p->b + m->in_offset; break; case BESHORT: offset = (short)((p->hs[0]<<8)|(p->hs[1]))+ - m->in.offset; + m->in_offset; break; case LESHORT: offset = (short)((p->hs[1]<<8)|(p->hs[0]))+ - m->in.offset; + m->in_offset; break; case SHORT: - offset = p->h + m->in.offset; + offset = p->h + m->in_offset; break; case BELONG: offset = (int32)((p->hl[0]<<24)|(p->hl[1]<<16)| (p->hl[2]<<8)|(p->hl[3]))+ - m->in.offset; + m->in_offset; break; case LELONG: offset = (int32)((p->hl[3]<<24)|(p->hl[2]<<16)| (p->hl[1]<<8)|(p->hl[0]))+ - m->in.offset; + m->in_offset; break; case LONG: - offset = p->l + m->in.offset; + offset = p->l + m->in_offset; break; }