Mask operations for PD file
Rob McMahon
cudcv at warwick.ac.uk
Sat Sep 2 07:08:39 AEST 1989
Ian Darwin's PD file command which came over the net supported a very limited
form of the `&' operator, which apparenty Sun added to the file command. The
file as distributed allowed:
>2 byte &0200
but there was no way to do
>2 byte&0177 =2
Here are some diffs to give it the full functionality. Also one small fix for
ANSI pre-processors which demand matching quotes even within comments, one not
to print a space if the description string from the magic file is empty
(useful when everything is going to be printed by continuation lines), and a
bug fix for strtol which meant that the pointer was incremented one to many
characters.
After the diffs are my modified versions of magdir/{sun,compress}. Note,
though, that I have to do
>0 byte&0200 0200 ...
rather than
>0 byte&0200 >0 ...
is it right that these comparisons should be signed ? When I think of a byte
I think 0--255, not -128--127 ...
Anyway, do with these patches what you will. Any improvements gratefully
received. Have fun.
===================================================================
RCS file: apprentice.c,v
retrieving revision 1.1
diff -c -r1.1 apprentice.c
*** /tmp/,RCSt1026546 Fri Sep 1 21:50:12 1989
--- apprentice.c Fri Sep 1 21:29:41 1989
***************
*** 67,73 ****
/* parse it */
if (check) /* print silly verbose header for USG compat. */
! (void) printf("cont\toffset\ttype\topcode\tvalue\tdesc\n");
while (fgets(line, MAXSTR, f) != NULL) {
if (line[0]=='#') /* comment, do not parse */
--- 67,73 ----
/* parse it */
if (check) /* print silly verbose header for USG compat. */
! (void) printf("cont\toffset\ttype\topcode\tmask\tvalue\tdesc\n");
while (fgets(line, MAXSTR, f) != NULL) {
if (line[0]=='#') /* comment, do not parse */
***************
*** 92,98 ****
int *ndx, check;
{
int i = 0, nd = *ndx;
- int slen;
static int warned = 0;
struct magic *m;
extern int errno;
--- 92,97 ----
***************
*** 152,161 ****
--- 151,205 ----
m->reln = '=';
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 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
+ */
+ EATAB;
+ while ((m->desc[i++] = *l++) != '\0' && i<MAXDESC)
+ /* NULLBODY */;
+
+ 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;
+
switch(m->type) {
/*
* Do not remove the casts below. They are vital.
***************
*** 163,178 ****
* have happened.
*/
case BYTE:
! m->value.l = (char) strtol(l,&l,0);
break;
case SHORT:
! m->value.l = (short) strtol(l,&l,0);
break;
case LONG:
! m->value.l = (long) strtol(l,&l,0);
break;
case STRING:
! l = getstr(l, m->value.s, sizeof(m->value.s), &slen);
m->vallen = slen;
break;
default:
--- 207,222 ----
* have happened.
*/
case BYTE:
! m->value.l = (char) strtol(*p,p,0);
break;
case SHORT:
! m->value.l = (short) strtol(*p,p,0);
break;
case LONG:
! m->value.l = (long) strtol(*p,p,0);
break;
case STRING:
! *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen);
m->vallen = slen;
break;
default:
***************
*** 179,196 ****
warning("can't happen: m->type=%d\n", m->type);
return -1;
}
-
- /*
- * 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;
}
--- 223,228 ----
===================================================================
RCS file: file.1,v
retrieving revision 1.1
diff -c -r1.1 file.1
*** /tmp/,RCSt1026546 Fri Sep 1 21:50:16 1989
--- file.1 Fri Sep 1 21:49:56 1989
***************
*** 149,165 ****
The Sun Microsystems implementation of System V compatibility
includes a file(1) command that has some extentions.
My version differs from Sun's only in minor ways.
! The significant one is the `&' operator, which Sun's program expects as,
for example,
..br
>16 long&0x7fffffff >0 not stripped
- ..br
- would be entered in my version as
- ..br
- >16 long &0x7fffffff not stripped
- ..br
- which is a little less general; it simply tests (location 16)&0x7ffffff
- and returns its truth value as a C expression.
..SH MAGIC DIRECTORY
The magic file entries have been collected from various sources,
mainly USENET, and contributed by various authors.
--- 149,158 ----
The Sun Microsystems implementation of System V compatibility
includes a file(1) command that has some extentions.
My version differs from Sun's only in minor ways.
! It includes the extension of the `&' operator, used as,
for example,
..br
>16 long&0x7fffffff >0 not stripped
..SH MAGIC DIRECTORY
The magic file entries have been collected from various sources,
mainly USENET, and contributed by various authors.
***************
*** 199,204 ****
--- 192,200 ----
Written by Ian F. Darwin, UUCP address {utzoo | ihnp4}!darwin!ian,
Internet address ian at sq.com,
postal address: P.O. Box 603, Station F, Toronto, Ontario, CANADA M4Y 2L8.
+ ..PP
+ Altered by Rob McMahon, cudcv at warwick.ac.uk, 1989, to extend the `&' operator
+ from simple `x&y != 0' to `x&y op z'.
..PP
..I Strtok.c
and
===================================================================
RCS file: file.h,v
retrieving revision 1.1
diff -c -r1.1 file.h
*** /tmp/,RCSt1026546 Fri Sep 1 21:50:23 1989
--- file.h Fri Sep 1 21:29:44 1989
***************
*** 35,41 ****
struct magic {
short contflag; /* 1 if '>0' appears */
long offset; /* offset to magic number */
! char reln; /* relation (0=eq, '>'=gt, etc) */
char type; /* int, short, long or string. */
char vallen; /* length of string value, if any */
#define BYTE 1
--- 35,42 ----
struct magic {
short contflag; /* 1 if '>0' appears */
long offset; /* offset to magic number */
! #define MASK 0200 /* this is a masked op, like & v1 = v2 */
! unsigned char reln; /* relation (0=eq, '>'=gt, etc) */
char type; /* int, short, long or string. */
char vallen; /* length of string value, if any */
#define BYTE 1
***************
*** 48,53 ****
--- 49,55 ----
long l;
char s[MAXstring];
} value; /* either number or string */
+ long mask; /* mask before comparison with value */
char desc[MAXDESC]; /* description */
};
===================================================================
RCS file: fsmagic.c,v
retrieving revision 1.1
diff -c -r1.1 fsmagic.c
*** /tmp/,RCSt1026546 Fri Sep 1 21:50:29 1989
--- fsmagic.c Fri Sep 1 21:29:47 1989
***************
*** 35,41 ****
/* On most systems cpp will discard it automatically */
Congratulations, you have found a portability bug.
Please grep /usr/include/sys and edit the above #include
! to point at the file that defines the `major' macro.
#endif /*major*/
#include <sys/stat.h>
#include "file.h"
--- 35,41 ----
/* On most systems cpp will discard it automatically */
Congratulations, you have found a portability bug.
Please grep /usr/include/sys and edit the above #include
! to point at the file that defines the ``major'' macro.
#endif /*major*/
#include <sys/stat.h>
#include "file.h"
===================================================================
RCS file: magic.4,v
retrieving revision 1.1
diff -c -r1.1 magic.4
*** /tmp/,RCSt1026546 Fri Sep 1 21:50:33 1989
--- magic.4 Fri Sep 1 21:50:00 1989
***************
*** 35,40 ****
--- 35,45 ----
..IP string
A string of bytes.
..RE
+ 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.
..IP test
The value to be compared with the value from the file. If the type is
numeric, this value
***************
*** 49,61 ****
..BR < ,
to specify that the value from the file must be less than the specified
value,
..BR > ,
to specify that the value from the file must be greater than the specified
! value,
or
- ..BR & ,
- to specify that the value is to be AND'ed with the
- numeric value before any comparisons are done.
Numeric values are specified in C form; e.g.
..B 13
is decimal,
--- 54,64 ----
..BR < ,
to specify that the value from the file must be less than the specified
value,
+ or
..BR > ,
to specify that the value from the file must be greater than the specified
! value.
or
Numeric values are specified in C form; e.g.
..B 13
is decimal,
===================================================================
RCS file: print.c,v
retrieving revision 1.1
diff -c -r1.1 print.c
*** /tmp/,RCSt1026546 Fri Sep 1 21:50:36 1989
--- print.c Fri Sep 1 21:29:49 1989
***************
*** 44,55 ****
mdump(m)
struct magic *m;
{
! (void) printf("%d\t%d\t%d\t%c\t",
m->contflag,
m->offset,
m->type,
! m->reln,
0);
if (m->type == STRING)
showstr(m->value.s);
else
--- 44,59 ----
mdump(m)
struct magic *m;
{
! (void) printf("%d\t%d\t%d\t%s%c\t",
m->contflag,
m->offset,
m->type,
! 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
===================================================================
RCS file: softmagic.c,v
retrieving revision 1.1
diff -c -r1.1 softmagic.c
*** /tmp/,RCSt1026546 Fri Sep 1 21:50:41 1989
--- softmagic.c Fri Sep 1 21:29:52 1989
***************
*** 71,77 ****
magindex < nmagic) {
++magindex;
if (mcheck(s, &magic[magindex])){
! (void) putchar(' ');
mprint(&magic[magindex],s);
}
}
--- 71,79 ----
magindex < nmagic) {
++magindex;
if (mcheck(s, &magic[magindex])){
! /* no space if nothing printed */
! if (magic[magindex-1].desc[0])
! (void) putchar(' ');
mprint(&magic[magindex],s);
}
}
***************
*** 98,110 ****
switch (m->type) {
case BYTE:
! (void) printf(m->desc, p->b);
break;
case SHORT:
! (void) printf(m->desc, p->h);
break;
case LONG:
! (void) printf(m->desc, p->l);
break;
case STRING:
if ((pp=strchr(p->s, '\n')) != NULL)
--- 100,115 ----
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)
***************
*** 123,128 ****
--- 128,134 ----
{
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) {
***************
*** 167,172 ****
--- 173,184 ----
return v < l;
case '&':
return v & l;
+ 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;
===================================================================
RCS file: strtol.c,v
retrieving revision 1.1
diff -c -r1.1 strtol.c
*** /tmp/,RCSt1026546 Fri Sep 1 21:50:44 1989
--- strtol.c Fri Sep 1 21:29:54 1989
***************
*** 89,95 ****
valid = 0;
break;
}
! ++s;
}
/*
--- 89,96 ----
valid = 0;
break;
}
! if (valid)
! ++s;
}
/*
------------------------------------------------------------------------------
# Values for Sun binaries
0 long&0x7cfffff0 0x30100 sparc
>2 short 0407
>2 short 0410 pure
>2 short 0413 demand paged
>0 byte&0200 0200 dynamically linked
>16 long >0 executable not stripped
>16 long =0 executable stripped
0 long&0x7cfffff0 0x20100 mc68020
>2 short 0407
>2 short 0410 pure
>2 short 0413 demand paged
>0 byte&0200 0200 dynamically linked
>16 long >0 executable not stripped
>16 long =0 executable stripped
0 long&0x7cfffff0 0x10100 mc68010
>2 short 0407
>2 short 0410 pure
>2 short 0413 demand paged
>0 byte&0200 0200 dynamically linked
>16 long >0 executable not stripped
>16 long =0 executable stripped
0 long&0x7cfffff0 0x100
#>2 short 0407
>2 short 0410 pure
>2 short 0413 demand paged
>0 byte&0200 0200 dynamically linked
>16 long >0 executable not stripped
>16 long =0 executable stripped
0 long 0x080456 core file
>128 string >0 from '%s'
#
0 short 05401 byte-swapped demand paged executable
0 short 010001 byte-swapped demand paged executable
------------------------------------------------------------------------------
0 short 017037 packed data
# CPL - added pack to /etc/magic
0 short 017436 packed data
0 short 0145405 huf output
0 string \037\235 compressed data
>2 byte&0200 0200 block compressed
# non block compressed
>2 byte&0177 >0 - with %d bits
------------------------------------------------------------------------------
Rob--
UUCP: ...!mcvax!ukc!warwick!cudcv PHONE: +44 203 523037
JANET: cudcv at uk.ac.warwick ARPA: cudcv at warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England
More information about the Comp.sources.bugs
mailing list