A four-byte value (on most systems) in little-endian byte order,
interpreted as a unix date.
.RE
+.PP
The numeric types may optionally be followed by
.B &
and a numeric value,
to specify that the value is to be AND'ed with the
-numeric value before any comparisons are done.
+numeric value before any comparisons are done. Prepending a
+.B u
+to the type indicates that ordered comparisons should be unsigned.
.IP test
The value to be compared with the value from the file. If the type is
numeric, this value
.\" the changes I posted to the S5R2 version.
.\"
.\" Modified for Ian Darwin's version of the file command.
-.\" @(#)$Id: magic.man,v 1.10 1993/02/19 14:22:46 ian Exp $
+.\" @(#)$Id: magic.man,v 1.11 1994/05/03 17:58:23 christos Exp $
#ifndef lint
static char *moduleid =
- "@(#)$Id: apprentice.c,v 1.18 1993/09/23 20:19:42 christos Exp $";
+ "@(#)$Id: apprentice.c,v 1.19 1994/05/03 17:58:23 christos Exp $";
#endif /* lint */
#define EATAB {while (isascii((unsigned char) *l) && \
isspace((unsigned char) *l)) ++l;}
-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 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 maxmagic = 0;
else
exit(1);
}
-
+
/* parse it */
if (check) /* print silly verbose header for USG compat. */
(void) printf("cont\toffset\ttype\topcode\tmask\tvalue\tdesc\n");
return errs ? -1 : 0;
}
+/*
+ * extend the sign bit if the comparison is to be signed
+ */
+unsigned long
+signextend(m, v)
+struct magic *m;
+unsigned long v;
+{
+ if (!(m->flag & UNSIGNED))
+ switch(m->type) {
+ /*
+ * Do not remove the casts below. They are
+ * vital. When later compared with the data,
+ * the sign extension must have happened.
+ */
+ case BYTE:
+ v = (char) v;
+ break;
+ case SHORT:
+ case BESHORT:
+ case LESHORT:
+ v = (short) v;
+ break;
+ case DATE:
+ case BEDATE:
+ case LEDATE:
+ case LONG:
+ case BELONG:
+ case LELONG:
+ v = (long) v;
+ break;
+ case STRING:
+ break;
+ default:
+ magwarn("can't happen: m->type=%d\n",
+ m->type);
+ return -1;
+ }
+ return v;
+}
+
/*
* parse one line from magic file, put into magic[index++] if valid
*/
#define NLELONG 6
#define NLEDATE 6
+ if (*l == 'u') {
+ ++l;
+ m->flag |= UNSIGNED;
+ }
+
/* get type, skip it */
if (strncmp(l, "byte", NBYTE)==0) {
m->type = BYTE;
/* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
if (*l == '&') {
++l;
- m->mask = strtol(l, &l, 0);
+ m->mask = signextend(m, strtol(l, &l, 0));
} else
- m->mask = 0L;
+ m->mask = ~0L;
EATAB;
switch (*l) {
if (m->type == STRING) {
*p = getstr(*p, m->value.s, sizeof(m->value.s), &slen);
m->vallen = slen;
- } else {
- if (m->reln != 'x') {
- switch(m->type) {
- /*
- * Do not remove the casts below. They are vital.
- * When later compared with the data, the sign
- * extension must have happened.
- */
- case BYTE:
- m->value.l = (char) strtol(*p,p,0);
- break;
- case SHORT:
- case BESHORT:
- case LESHORT:
- m->value.l = (short) strtol(*p,p,0);
- break;
- case DATE:
- case BEDATE:
- case LEDATE:
- case LONG:
- case BELONG:
- case LELONG:
- m->value.l = (long) strtol(*p,p,0);
- break;
- default:
- magwarn("can't happen: m->type=%d\n", m->type);
- return -1;
- }
- }
- }
+ } else
+ if (m->reln != 'x')
+ m->value.l = signextend(m, strtol(*p, p, 0));
return 0;
}
/*
* file.h - definitions for file(1) program
- * @(#)$Id: file.h,v 1.18 1993/10/27 20:59:05 christos Exp $
+ * @(#)$Id: file.h,v 1.19 1994/05/03 17:58:23 christos Exp $
*
* Copyright (c) Ian F. Darwin, 1987.
* Written by Ian F. Darwin.
struct magic {
short flag;
#define INDIR 1 /* if '>(...)' appears, */
+#define UNSIGNED 2 /* comparison is unsigned */
short cont_level; /* level of ">" */
struct {
char type; /* byte short long */
#define LELONG 11
#define LEDATE 12
union VALUETYPE {
- char b;
- short h;
- long l;
+ unsigned char b;
+ unsigned short h;
+ unsigned long 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" */
} value; /* either number or string */
- long mask; /* mask before comparison with value */
+ unsigned long mask; /* mask before comparison with value */
char nospflag; /* supress space character */
char desc[MAXDESC]; /* description */
};
extern void tryit __P((unsigned char *, int, int));
extern int zmagic __P((unsigned char *, int));
extern void ckfprintf __P((FILE *, const char *, ...));
+extern unsigned long signextend __P((struct magic *, unsigned long));
#define FILE_VERSION_MAJOR 3
-#define patchlevel 13
+#define patchlevel 14
/*
* Patchlevel file for Ian Darwin's MAGIC command.
- * $Id: patchlevel.h,v 1.13 1994/01/21 01:27:01 christos Exp $
+ * $Id: patchlevel.h,v 1.14 1994/05/03 17:58:23 christos Exp $
*
* $Log: patchlevel.h,v $
- * Revision 1.13 1994/01/21 01:27:01 christos
+ * Revision 1.14 1994/05/03 17:58:23 christos
+ * changes from mycroft@gnu.ai.mit.edu (Charles Hannum) for unsigned
+ *
+ * Revision 1.13 1994/01/21 01:27:01 christos
* Fixed null termination bug from Don Seeley at BSDI in ascmagic.c
*
* Revision 1.12 1993/10/27 20:59:05 christos
#ifndef lint
static char *moduleid =
- "@(#)$Id: print.c,v 1.20 1993/09/23 20:26:25 christos Exp $";
+ "@(#)$Id: print.c,v 1.21 1994/05/03 17:58:23 christos Exp $";
#endif /* lint */
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
mdump(m)
struct magic *m;
{
- static char *offs[] = { "absolute", "offset",
- "indirect", "indirect-offset" };
static char *typ[] = { "invalid", "byte", "short", "invalid",
"long", "string", "date", "beshort",
"belong", "bedate", "leshort", "lelong",
"ledate" };
- (void) fprintf(stderr, "[%s,%d,",
- (m->flag >= 0 && m->flag < SZOF(offs) ? offs[m->flag]: "*bad*"),
- m->offset);
-
+ (void) fputc('[', stderr);
+ (void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7),
+ m->offset);
if (m->flag & INDIR)
- (void) fprintf(stderr, "(%s,%d),",
- (m->in.type >= 0 &&
- m->in.type < SZOF(typ) ?
- typ[(unsigned char) m->in.type] : "*bad*"),
- m->in.offset);
+ (void) fprintf(stderr, "(%s,%d),",
+ (m->in.type >= 0 && m->in.type < SZOF(typ)) ?
+ typ[(unsigned char) m->in.type] :
+ "*bad*",
+ m->in.offset);
- (void) fputs((m->type >= 0 && m->type < SZOF(typ)) ?
- typ[(unsigned char) m->type] :
- "*bad*",
- stderr);
+ (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
+ (m->type >= 0 && m->type < SZOF(typ)) ?
+ typ[(unsigned char) m->type] :
+ "*bad*");
+ if (m->mask != ~0L)
+ (void) fprintf(stderr, " & %.8x", m->mask);
- if (m->reln == 'x')
- (void) fputs(",*any*", stderr);
- else
- (void) fprintf(stderr, ",%c", m->reln);
+ (void) fprintf(stderr, ",%c", m->reln);
if (m->reln != 'x') {
switch (m->type) {
#ifndef lint
static char *moduleid =
- "@(#)$Id: softmagic.c,v 1.24 1993/10/27 20:59:05 christos Exp $";
+ "@(#)$Id: softmagic.c,v 1.25 1994/05/03 17:58:23 christos Exp $";
#endif /* lint */
static int match __P((unsigned char *, int));
struct magic *m;
{
char *pp, *rt;
- unsigned long mask = m->mask ? m->mask : ~0;
+ unsigned long v;
+
switch (m->type) {
case BYTE:
- (void) printf(m->desc, (unsigned char) p->b & mask);
- break;
+ v = p->b;
+ break;
+
case SHORT:
case BESHORT:
case LESHORT:
- (void) printf(m->desc, (unsigned short) p->h & mask);
- break;
+ v = p->h;
+ break;
+
case LONG:
case BELONG:
case LELONG:
- (void) printf(m->desc, (unsigned long) p->l & mask);
+ v = p->l;
break;
+
case STRING:
if (m->reln == '=') {
(void) printf(m->desc, m->value.s);
*rt = '\0';
(void) printf(m->desc, p->s);
}
- break;
+ return;
+
case DATE:
case BEDATE:
case LEDATE:
if ((rt = strchr(pp, '\n')) != NULL)
*rt = '\0';
(void) printf(m->desc, pp);
- break;
+ return;
default:
error("invalid m->type (%d) in mprint().\n", m->type);
/*NOTREACHED*/
}
+
+ v = signextend(m, v) & m->mask;
+ (void) printf(m->desc, (unsigned char) v);
}
/*
union VALUETYPE* p;
struct magic *m;
{
- register long l = m->value.l;
- register long v;
+ register unsigned long l = m->value.l;
+ register unsigned long v;
+ int matched;
if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
fprintf(stderr, "BOINK");
return 0;/*NOTREACHED*/
}
- if (m->mask != 0L)
- v &= m->mask;
+ v = signextend(m, v) & m->mask;
switch (m->reln) {
case 'x':
if (debug)
(void) fprintf(stderr, "%d == *any* = 1\n", v);
- return 1;
+ matched = 1;
+ break;
+
case '!':
if (debug)
(void) fprintf(stderr, "%d != %d = %d\n", v, l, v != l);
- return v != l;
+ matched = v != l;
+ break;
+
case '=':
if (debug)
(void) fprintf(stderr, "%d == %d = %d\n", v, l, v == l);
- return v == l;
+ matched = v == l;
+ break;
+
case '>':
if (debug)
(void) fprintf(stderr, "%d > %d = %d\n", v, l, v > l);
- return v > l;
+ matched = v > l;
+ break;
+
case '<':
if (debug)
(void) fprintf(stderr, "%d < %d = %d\n", v, l, v < l);
- return v < l;
+ matched = v < l;
+ break;
+
case '&':
if (debug)
(void) fprintf(stderr, "((%x & %x) == %x) = %d\n",
v, l, l, (v & l) == l);
- return (v & l) == l;
+ matched = (v & l) == l;
+ break;
+
case '^':
if (debug)
(void) fprintf(stderr, "((%x & %x) != %x) = %d\n",
v, l, l, (v & l) != l);
- return (v & l) != l;
+ matched = (v & l) != l;
+ break;
+
default:
+ matched = 0;
error("mcheck: can't happen: invalid relation %d.\n", m->reln);
- return 0;/*NOTREACHED*/
+ break;/*NOTREACHED*/
}
+
+ return matched;
}