From 02e9c6b1bd102ba377144be201bd9e135ccbd9fd Mon Sep 17 00:00:00 2001 From: Christos Zoulas Date: Thu, 20 Oct 2005 14:59:00 +0000 Subject: [PATCH] Middle endian additions, from Diomidis Spinellis --- ChangeLog | 5 ++ doc/magic.man | 25 ++++++++-- magic/Magdir/dump | 12 +++++ src/apprentice.c | 20 +++++++- src/file.h | 15 ++++-- src/print.c | 5 +- src/softmagic.c | 120 +++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 192 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2ec30bf..c28bd399 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ + +2005-10-20 11:15 Christos Zoulas + + * Middle Endian magic (Diomidis Spinellis) + 2005-10-17 11:15 Christos Zoulas * Open with O_BINARY for CYGWIN (Corinna Vinschen) diff --git a/doc/magic.man b/doc/magic.man index d0a7d7d6..5d7ec6fa 100644 --- a/doc/magic.man +++ b/doc/magic.man @@ -77,6 +77,15 @@ interpreted as a UNIX date. A four-byte value (on most systems) in little-endian byte order, interpreted as a UNIX-style date, but interpreted as local time rather than UTC. +.IP melong +A four-byte value (on most systems) in middle-endian (PDP-11) byte order. +.IP medate +A four-byte value (on most systems) in middle-endian (PDP-11) byte order, +interpreted as a UNIX date. +.IP meldate +A four-byte value (on most systems) in middle-endian (PDP-11) byte order, +interpreted as a UNIX-style date, but interpreted as local time rather +than UTC. .IP regex A regular expression match in extended POSIX regular expression syntax (much like egrep). @@ -228,11 +237,14 @@ The value of .I x is used as an offset in the file. A byte, short or long is read at that offset depending on the -.B [bslBSL] +.B [bslBSLm] type specifier. The capitalized types interpret the number as a big endian value, whereas the small letter versions interpret the number as a little -endian value. +endian value; +the +.B m +type interprets the number as a middle endian (PDP-11) value. To that number the value of .I y is added and the result is used as an offset in the file. @@ -340,13 +352,18 @@ The formats .IR long , .IR belong , .IR lelong , +.IR melong , .IR short , .IR beshort , .IR leshort , .IR date , .IR bedate , +.IR medate , +.IR ledate , +.IR beldate , +.IR leldate , and -.I ledate +.I meldate are system-dependent; perhaps they should be specified as a number of bytes (2B, 4B, etc), since the files being recognized typically come from @@ -370,4 +387,4 @@ indirect offsets. .\" the changes I posted to the S5R2 version. .\" .\" Modified for Ian Darwin's version of the file command. -.\" @(#)$Id: magic.man,v 1.28 2005/03/17 17:34:15 christos Exp $ +.\" @(#)$Id: magic.man,v 1.29 2005/10/20 14:59:01 christos Exp $ diff --git a/magic/Magdir/dump b/magic/Magdir/dump index 628ead86..addd9549 100644 --- a/magic/Magdir/dump +++ b/magic/Magdir/dump @@ -79,3 +79,15 @@ >760 string >\0 Device %s, >824 string >\0 Host %s, >888 lelong >0 Flags %x + +18 leshort 60011 old-fs dump file (16-bit, assuming PDP-11 endianness), +>2 medate x Previous dump %s, +>6 medate x This dump %s, +>10 leshort >0 Volume %ld, +>0 leshort 1 tape header. +>0 leshort 2 beginning of file record. +>0 leshort 3 map of inodes on tape. +>0 leshort 4 continuation of file record. +>0 leshort 5 end of volume. +>0 leshort 6 map of inodes deleted. +>0 leshort 7 end of medium (for floppy). diff --git a/src/apprentice.c b/src/apprentice.c index 977821f2..37a5195f 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -45,7 +45,7 @@ #endif #ifndef lint -FILE_RCSID("@(#)$Id: apprentice.c,v 1.85 2005/10/17 15:31:10 christos Exp $") +FILE_RCSID("@(#)$Id: apprentice.c,v 1.86 2005/10/20 14:59:01 christos Exp $") #endif /* lint */ #define EATAB {while (isascii((unsigned char) *l) && \ @@ -366,12 +366,15 @@ file_signextend(struct magic_set *ms, struct magic *m, uint32_t v) case FILE_DATE: case FILE_BEDATE: case FILE_LEDATE: + case FILE_MEDATE: case FILE_LDATE: case FILE_BELDATE: case FILE_LELDATE: + case FILE_MELDATE: case FILE_LONG: case FILE_BELONG: case FILE_LELONG: + case FILE_MELONG: v = (int32_t) v; break; case FILE_STRING: @@ -463,6 +466,9 @@ parse(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, char *l, case 'L': m->in_type = FILE_BELONG; break; + case 'm': + m->in_type = FILE_MELONG; + break; case 'h': case 's': m->in_type = FILE_LESHORT; @@ -555,11 +561,14 @@ parse(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, char *l, #define NBEDATE 6 #define NLESHORT 7 #define NLELONG 6 +#define NMELONG 6 #define NLEDATE 6 +#define NMEDATE 6 #define NPSTRING 7 #define NLDATE 5 #define NBELDATE 7 #define NLELDATE 7 +#define NMELDATE 7 #define NREGEX 5 #define NBESTRING16 10 #define NLESTRING16 10 @@ -604,9 +613,15 @@ parse(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, char *l, } else if (strncmp(l, "lelong", NLELONG)==0) { m->type = FILE_LELONG; l += NLELONG; + } else if (strncmp(l, "melong", NMELONG)==0) { + m->type = FILE_MELONG; + l += NMELONG; } else if (strncmp(l, "ledate", NLEDATE)==0) { m->type = FILE_LEDATE; l += NLEDATE; + } else if (strncmp(l, "medate", NMEDATE)==0) { + m->type = FILE_MEDATE; + l += NMEDATE; } else if (strncmp(l, "pstring", NPSTRING)==0) { m->type = FILE_PSTRING; l += NPSTRING; @@ -619,6 +634,9 @@ parse(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, char *l, } else if (strncmp(l, "leldate", NLELDATE)==0) { m->type = FILE_LELDATE; l += NLELDATE; + } else if (strncmp(l, "meldate", NMELDATE)==0) { + m->type = FILE_MELDATE; + l += NMELDATE; } else if (strncmp(l, "regex", NREGEX)==0) { m->type = FILE_REGEX; l += NREGEX; diff --git a/src/file.h b/src/file.h index 0a465156..8ef2fbaa 100644 --- a/src/file.h +++ b/src/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$Id: file.h,v 1.72 2005/10/17 15:36:22 christos Exp $ + * @(#)$Id: file.h,v 1.73 2005/10/20 14:59:01 christos Exp $ */ #ifndef __file_h__ @@ -113,6 +113,9 @@ struct magic { #define FILE_BESTRING16 18 #define FILE_LESTRING16 19 #define FILE_SEARCH 20 +#define FILE_MEDATE 21 +#define FILE_MELDATE 22 +#define FILE_MELONG 23 #define FILE_FORMAT_NAME \ /* 0 */ "invalid 0", \ @@ -135,7 +138,10 @@ struct magic { /* 17 */ "regex", \ /* 18 */ "bestring16", \ /* 19 */ "lestring16", \ -/* 20 */ "search", +/* 20 */ "search", \ +/* 21 */ "medate", \ +/* 22 */ "meldate", \ +/* 23 */ "melong", #define FILE_FMT_NUM "cduxXi" #define FILE_FMT_STR "s" @@ -161,7 +167,10 @@ struct magic { /* 17 */ FILE_FMT_STR, \ /* 18 */ FILE_FMT_STR, \ /* 19 */ FILE_FMT_STR, \ -/* 20 */ FILE_FMT_STR, +/* 20 */ FILE_FMT_STR, \ +/* 21 */ FILE_FMT_STR, \ +/* 22 */ FILE_FMT_STR, \ +/* 23 */ FILE_FMT_NUM, /* Word 3 */ uint8_t in_op; /* operator for indirection */ diff --git a/src/print.c b/src/print.c index 97c743c3..11e3b6c9 100644 --- a/src/print.c +++ b/src/print.c @@ -41,7 +41,7 @@ #include #ifndef lint -FILE_RCSID("@(#)$Id: print.c,v 1.48 2005/10/12 19:29:42 christos Exp $") +FILE_RCSID("@(#)$Id: print.c,v 1.49 2005/10/20 14:59:01 christos Exp $") #endif /* lint */ #define SZOF(a) (sizeof(a) / sizeof(a[0])) @@ -101,6 +101,7 @@ file_mdump(struct magic *m) case FILE_LONG: case FILE_LESHORT: case FILE_LELONG: + case FILE_MELONG: case FILE_BESHORT: case FILE_BELONG: (void) fprintf(stderr, "%d", m->value.l); @@ -113,12 +114,14 @@ file_mdump(struct magic *m) case FILE_DATE: case FILE_LEDATE: case FILE_BEDATE: + case FILE_MEDATE: (void)fprintf(stderr, "%s,", file_fmttime(m->value.l, 1)); break; case FILE_LDATE: case FILE_LELDATE: case FILE_BELDATE: + case FILE_MELDATE: (void)fprintf(stderr, "%s,", file_fmttime(m->value.l, 0)); break; diff --git a/src/softmagic.c b/src/softmagic.c index 2d2742f7..2e78fdcb 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -39,7 +39,7 @@ #ifndef lint -FILE_RCSID("@(#)$Id: softmagic.c,v 1.76 2005/10/17 19:04:36 christos Exp $") +FILE_RCSID("@(#)$Id: softmagic.c,v 1.77 2005/10/20 14:59:01 christos Exp $") #endif /* lint */ private int match(struct magic_set *, struct magic *, uint32_t, @@ -272,6 +272,7 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m) case FILE_LONG: case FILE_BELONG: case FILE_LELONG: + case FILE_MELONG: v = file_signextend(ms, m, p->l); if (file_printf(ms, m->desc, (uint32_t) v) == -1) return -1; @@ -302,6 +303,7 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m) case FILE_DATE: case FILE_BEDATE: case FILE_LEDATE: + case FILE_MEDATE: if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1) return -1; t = m->offset + sizeof(time_t); @@ -310,6 +312,7 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m) case FILE_LDATE: case FILE_BELDATE: case FILE_LELDATE: + case FILE_MELDATE: if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1) return -1; t = m->offset + sizeof(time_t); @@ -597,6 +600,41 @@ mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m) if (m->mask_op & FILE_OPINVERSE) p->l = ~p->l; return 1; + case FILE_MELONG: + case FILE_MEDATE: + case FILE_MELDATE: + p->l = (int32_t) + ((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2])); + if (m->mask) + switch (m->mask_op&0x7F) { + case FILE_OPAND: + p->l &= m->mask; + break; + case FILE_OPOR: + p->l |= m->mask; + break; + case FILE_OPXOR: + p->l ^= m->mask; + break; + case FILE_OPADD: + p->l += m->mask; + break; + case FILE_OPMINUS: + p->l -= m->mask; + break; + case FILE_OPMULTIPLY: + p->l *= m->mask; + break; + case FILE_OPDIVIDE: + p->l /= m->mask; + break; + case FILE_OPMODULO: + p->l %= m->mask; + break; + } + if (m->mask_op & FILE_OPINVERSE) + p->l = ~p->l; + return 1; case FILE_REGEX: case FILE_SEARCH: return 1; @@ -727,6 +765,10 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s, off = (int32_t)((q->hl[3]<<24)|(q->hl[2]<<16)| (q->hl[1]<<8)|(q->hl[0])); break; + case FILE_MELONG: + off = (int32_t)((q->hl[1]<<24)|(q->hl[0]<<16)| + (q->hl[3]<<8)|(q->hl[2])); + break; } } switch (m->in_type) { @@ -1044,6 +1086,76 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s, if (m->in_op & FILE_OPINVERSE) offset = ~offset; break; + case FILE_MELONG: + if (nbytes < (offset + 4)) + return 0; + if (off) { + switch (m->in_op & 0x7F) { + case FILE_OPAND: + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])) & + off; + break; + case FILE_OPOR: + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])) | + off; + break; + case FILE_OPXOR: + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])) ^ + off; + break; + case FILE_OPADD: + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])) + + off; + break; + case FILE_OPMINUS: + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])) - + off; + break; + case FILE_OPMULTIPLY: + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])) * + off; + break; + case FILE_OPDIVIDE: + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])) / + off; + break; + case FILE_OPMODULO: + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])) % + off; + break; + } + } else + offset = (int32_t)((p->hl[1]<<24)| + (p->hl[0]<<16)| + (p->hl[3]<<8)| + (p->hl[2])); + if (m->in_op & FILE_OPINVERSE) + offset = ~offset; + break; case FILE_LONG: if (nbytes < (offset + 4)) return 0; @@ -1117,12 +1229,15 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s, case FILE_LONG: case FILE_BELONG: case FILE_LELONG: + case FILE_MELONG: case FILE_DATE: case FILE_BEDATE: case FILE_LEDATE: + case FILE_MEDATE: case FILE_LDATE: case FILE_BELDATE: case FILE_LELDATE: + case FILE_MELDATE: if (nbytes < (offset + 4)) return 0; break; @@ -1181,12 +1296,15 @@ mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m) case FILE_LONG: case FILE_BELONG: case FILE_LELONG: + case FILE_MELONG: case FILE_DATE: case FILE_BEDATE: case FILE_LEDATE: + case FILE_MEDATE: case FILE_LDATE: case FILE_BELDATE: case FILE_LELDATE: + case FILE_MELDATE: v = p->l; break; -- 2.40.0