From 671b80c82c4bced16c6a726c5152bd84d9751fcf Mon Sep 17 00:00:00 2001 From: Ian Darwin Date: Fri, 19 Feb 1993 14:22:48 +0000 Subject: [PATCH] Part of Guy Harris' Jan-93 rewrite, including: Add in support for multiple levels of continuation. Add in support for "beshort", "belong", "bedate", "leshort", "lelong", and "ledate" types. Also, make old-style "not set"ting - "0 byte ^0x80 statically linked", meaning "this line matches if any of the bits in the value *aren't* set in the number from the file" - work. --- src/softmagic.c | 114 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 13 deletions(-) diff --git a/src/softmagic.c b/src/softmagic.c index df0efb3e..4271ba94 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -34,7 +34,7 @@ #ifndef lint static char *moduleid = - "@(#)$Id: softmagic.c,v 1.16 1992/09/14 14:17:02 ian Exp $"; + "@(#)$Id: softmagic.c,v 1.17 1993/02/19 14:22:48 ian Exp $"; #endif /* lint */ static int match __P((unsigned char *)); @@ -59,35 +59,100 @@ int nbytes; } /* - * go through the whole list, stopping if you find a match. - * Be sure to process every continuation of this match. + * Go through the whole list, stopping if you find a match. Process all + * the continuations of that match before returning. + * + * We support multi-level continuations: + * + * At any time when processing a successful top-level match, there is a + * current continuation level; it represents the level of the last + * successfully matched continuation. + * + * Continuations above that level are skipped as, if we see one, it + * means that the continuation that controls them - i.e, the + * lower-level continuation preceding them - failed to match. + * + * Continuations below that level are processed as, if we see one, + * it means we've finished processing or skipping higher-level + * continuations under the control of a successful or unsuccessful + * lower-level continuation, and are now seeing the next lower-level + * continuation and should process it. The current continuation + * level reverts to the level of the one we're seeing. + * + * Continuations at the current level are processed as, if we see + * one, there's no lower-level continuation that may have failed. + * + * If a continuation matches, we bump the current continuation level + * so that higher-level continuations are processed. */ static int match(s) unsigned char *s; { int magindex = 0; + int cont_level = 0; + int need_separator = 0; + while (magindex < nmagic) { /* if main entry matches, print it... */ if (mcheck(s, &magic[magindex])) { mprint(&magic[magindex],s); + /* + * If we printed something, we'll need to print + * a blank before we print something else. + */ + if (magic[magindex].desc[0]) + need_separator = 1; /* and any continuations that match */ - while (magic[magindex+1].flag && + cont_level++; + while (magic[magindex+1].cont_level != 0 && magindex < nmagic) { ++magindex; - if (mcheck(s, &magic[magindex])) { - /* space if previous printed */ - if (magic[magindex-1].desc[0] - && (magic[magindex].nospflag == 0) - ) - (void) putchar(' '); - mprint(&magic[magindex],s); + if (cont_level >= + magic[magindex].cont_level) { + if (cont_level > + magic[magindex].cont_level) { + /* + * We're at the end of the + * level-"cont_level" + * continuations. + */ + cont_level = + magic[magindex].cont_level; + } + if (mcheck(s, &magic[magindex])) { + /* + * This continuation matched. + * Print its message, with + * a blank before it if + * the previous item printed + * and this item isn't empty. + */ + /* space if previous printed */ + if (need_separator + && (magic[magindex].nospflag == 0) + && (magic[magindex].desc[0] != '\0') + ) { + (void) putchar(' '); + need_separator = 0; + } + mprint(&magic[magindex],s); + if (magic[magindex].desc[0]) + need_separator = 1; + + /* + * If we see any continuations + * at a higher level, + * process them. + */ + cont_level++; + } } } return 1; /* all through */ } else { /* main entry didn't match, flush its continuation */ - while (magic[magindex+1].flag && + while (magic[magindex+1].cont_level != 0 && magindex < nmagic) { ++magindex; } @@ -111,10 +176,14 @@ unsigned char *s; (m->reln & MASK) ? p->b & m->mask : p->b); break; case SHORT: + case BESHORT: + case LESHORT: (void) printf(m->desc, (m->reln & MASK) ? p->h & m->mask : p->h); break; case LONG: + case BELONG: + case LELONG: (void) printf(m->desc, (m->reln & MASK) ? p->l & m->mask : p->l); break; @@ -126,6 +195,8 @@ unsigned char *s; *rt = '\n'; break; case DATE: + case BEDATE: + case LEDATE: pp = ctime((time_t*) &p->l); if ((rt = strchr(pp, '\n')) != NULL) *rt = '\0'; @@ -185,6 +256,22 @@ struct magic *m; break; } break; + case BESHORT: + v = (short)((p->hs[0]<<8)|(p->hs[1])); + break; + case BELONG: + case BEDATE: + v = (long) + ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3])); + break; + case LESHORT: + v = (short)((p->hs[1]<<8)|(p->hs[0])); + break; + case LELONG: + case LEDATE: + v = (long) + ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0])); + break; default: error("invalid type %d in mcheck().\n", m->type); return -1;/*NOTREACHED*/ @@ -197,7 +284,6 @@ struct magic *m; case 'x': return 1; case '!': - case '^': return v != l; case '=': return v == l; @@ -207,6 +293,8 @@ struct magic *m; return v < l; case '&': return (v & l) == l; + case '^': + return (v & l) != l; case MASK | '=': return (v & mask) == l; case MASK | '>': -- 2.40.0