#ifndef lint
static char *moduleid =
- "@(#)$Header: /home/glen/git/file/cvs/file/src/apprentice.c,v 1.9 1990/10/03 17:52:59 ian Exp $";
+ "@(#)$Header: /home/glen/git/file/cvs/file/src/apprentice.c,v 1.10 1992/05/21 16:15:12 ian Exp $";
#endif /* lint */
#define MAXSTR 500
/* parse it */
if (check) /* print silly verbose header for USG compat. */
- (void) printf("cont\toffset\ttype\topcode\tvalue\tdesc\n");
+ (void) printf("cont\toffset\ttype\topcode\tmask\tvalue\tdesc\n");
while (fgets(line, MAXSTR, f) != NULL) {
if (line[0]=='#') /* comment, do not parse */
int *ndx, check;
{
int i = 0, nd = *ndx;
- int slen;
static int warned = 0;
struct magic *m;
extern int errno;
m->contflag = 0;
/* get offset, then skip over it */
+#ifdef OldWay
m->offset = atoi(l);
while (isascii(*l) && isdigit(*l))
++l;
+#else
+ m->offset = (int) strtol(l,&l,0);
+#endif
EATAB;
#define NBYTE 4
} else
m->mask = 0L;
EATAB;
+
+ switch (*l) {
+ case '>':
+ case '<':
+ case '&':
+ case '=':
+ m->reln = *l;
+ ++l;
+ break;
+ case '!':
+ case '^':
+ if (m->type != STRING) {
+ m->reln = *l;
+ ++l;
+ break;
+ }
+ /* FALL THROUGH */
+ default:
+ if (*l == 'x' && isascii(l[1]) && isspace(l[1])) {
+ m->reln = *l;
+ ++l;
+ goto GetDesc; /* Bill The Cat */
+ }
+ m->reln = '=';
+ break;
+ }
+ EATAB;
+
+ if (getvalue(m, &l))
+ return -1;
+ /*
+ * TODO finish this macro and start using it!
+ * #define offsetcheck {if (offset > HOWMANY-1)
+ * warning("offset too big"); }
+ */
- if (*l == '>' || *l == '<' || *l == '='
- || (m->type != STRING && (*l == '&' || *l == '^' || *l == 'x'))) {
- m->reln = *l;
+ /*
+ * if the relation was ``&'',
+ * change it to a MASK op relation.
+ */
+ EATAB;
+ if (m->reln == '&') {
+ if (*l == '>' || *l == '<' || *l == '=') {
+ m->reln = *l | MASK;
+ ++l;
+ } else
+ m->reln = '=' | MASK;
+ m->mask = m->value.l;
+ EATAB;
+ if (getvalue(m, &l))
+ return -1;
+ }
+
+ /*
+ * now get last part - the description
+ */
+GetDesc:
+ EATAB;
+ if (l[0] == '\b') {
+ ++l;
+ m->nospflag = 1;
+ } else if ((l[0] == '\\') && (l[1] == 'b')) {
++l;
+ ++l;
+ m->nospflag = 1;
} else
- m->reln = '=';
- EATAB;
+ m->nospflag = 0;
+ while ((m->desc[i++] = *l++) != '\0' && i<MAXDESC)
+ /* NULLBODY */;
-/*
- * TODO finish this macro and start using it!
- * #define offsetcheck {if (offset > HOWMANY-1) warning("offset too big"); }
+ if (check) {
+ mdump(m);
+ }
+ ++(*ndx); /* make room for next */
+ return 0;
+}
+
+/*
+ * Read a numeric value from a pointer, into the value union of a magic
+ * pointer, according to the magic type. Update the string pointer to point
+ * just after the number read. Return 0 for success, non-zero for failure.
*/
+int
+getvalue(m, p)
+ struct magic *m;
+ char **p;
+{
+ int slen;
+
if (m->type == STRING) {
- l = getstr(l, m->value.s, sizeof(m->value.s), &slen);
+ *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen);
m->vallen = slen;
} else {
if (m->reln != 'x') {
* extension must have happened.
*/
case BYTE:
- m->value.l = (char) strtol(l,&l,0);
+ m->value.l = (char) strtol(*p,p,0);
break;
case SHORT:
- m->value.l = (short) strtol(l,&l,0);
+ m->value.l = (short) strtol(*p,p,0);
break;
case LONG:
- m->value.l = (long) strtol(l,&l,0);
+ m->value.l = (long) strtol(*p,p,0);
break;
default:
warning("can't happen: m->type=%d\n", m->type);
}
}
}
-
- /*
- * now get last part - the description
- */
- EATAB;
- while ((m->desc[i++] = *l++) != '\0' && i<MAXDESC)
- /* NULLBODY */;
-
- if (check) {
- mdump(m);
- }
- ++(*ndx); /* make room for next */
return 0;
}
register int c;
register int val;
- while((c = *s++) != '\0') {
+ while ((c = *s++) != '\0') {
if (isspace(c))
break;
if (p >= pmax) {
#ifndef lint
static char *moduleid =
- "@(#)$Header: /home/glen/git/file/cvs/file/src/print.c,v 1.10 1987/11/12 13:00:24 ian Exp $";
+ "@(#)$Header: /home/glen/git/file/cvs/file/src/print.c,v 1.11 1992/05/21 16:16:43 ian Exp $";
#endif /* lint */
#define MAXSTR 500
mdump(m)
struct magic *m;
{
- (void) printf("%d\t%d\t%d\t%c\t",
+ (void) printf("%d\t%d\t%d\t%s%c\t",
m->contflag,
m->offset,
m->type,
- m->reln,
+ m->reln & MASK ? "&" : "",
+ m->reln & ~MASK,
0);
+ if (m->reln & MASK)
+ (void) printf("%d",m->mask);
+ (void) putchar('\t');
if (m->type == STRING)
showstr(m->value.s);
else
int myerrno;
myerrno = errno;
+
+ /* cuz we use stdout for most, stderr here */
+ (void) fflush(stdout);
+
if (progname != NULL) {
(void) fputs(progname, stderr);
(void) putc(':', stderr);
#ifndef lint
static char *moduleid =
- "@(#)$Header: /home/glen/git/file/cvs/file/src/softmagic.c,v 1.9 1991/01/23 13:56:45 ian Exp $";
+ "@(#)$Header: /home/glen/git/file/cvs/file/src/softmagic.c,v 1.10 1992/05/21 16:16:41 ian Exp $";
#endif /* lint */
extern char *progname;
while (magic[magindex+1].contflag &&
magindex < nmagic) {
++magindex;
- if (mcheck(s, &magic[magindex])){
- (void) putchar(' ');
+ 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);
}
}
unsigned char *s;
{
register union VALUETYPE *p = (union VALUETYPE *)(s+m->offset);
- register long v;
char *pp, *strchr();
- if (m->type == STRING) {
+ switch (m->type) {
+ case BYTE:
+ (void) printf(m->desc,
+ (m->reln & MASK) ? p->b & m->mask : p->b);
+ break;
+ case SHORT:
+ (void) printf(m->desc,
+ (m->reln & MASK) ? p->h & m->mask : p->h);
+ break;
+ case LONG:
+ (void) printf(m->desc,
+ (m->reln & MASK) ? p->l & m->mask : p->l);
+ break;
+ case STRING:
if ((pp=strchr(p->s, '\n')) != NULL)
*pp = '\0';
(void) printf(m->desc, p->s);
- } else {
- switch (m->type) {
- case BYTE:
- v = p->b; break;
- case SHORT:
- v = p->h; break;
- case LONG:
- v = p->l; break;
- default:
- warning("invalid m->type (%d) in mprint()", m->type);
- v = 0L;
- }
- if (m->mask != 0)
- v &= m->mask;
- (void) printf(m->desc, v);
+ break;
+ default:
+ warning("invalid m->type (%d) in mprint()", m->type);
+ break;
}
}
{
register union VALUETYPE *p = (union VALUETYPE *)(s+m->offset);
register long l = m->value.l;
+ register long mask = m->mask;
register long v;
if (debug) {
(void) printf("mcheck: %10.10s ", s);
mdump(m);
}
+
+ if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
+ printf("BOINK");
+ return 1;
+ }
+
switch (m->type) {
case BYTE:
v = p->b; break;
v &= m->mask;
switch (m->reln) {
+ case 'x':
+ return 1;
+ case '!':
+ case '^':
+ return v != l;
case '=':
return v == l;
case '>':
return v < l;
case '&':
return (v & l) == l;
- case '^':
- return (v & l) != l;
- case 'x':
- return 1;
+ case MASK | '=':
+ return (v & mask) == l;
+ case MASK | '>':
+ return (v & mask) > l;
+ case MASK | '<':
+ return (v & mask) < l;
default:
warning("mcheck: can't happen: invalid relation %d", m->reln);
return 0;