summaryrefslogtreecommitdiffstats
path: root/contrib/file/softmagic.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2008-01-13 20:35:16 +0000
committerobrien <obrien@FreeBSD.org>2008-01-13 20:35:16 +0000
commit6678cf7c2ac8c768ea5efe9fe0392f07e522c963 (patch)
tree5ce2a6ee53483b8b3a7ac87258304920c043207f /contrib/file/softmagic.c
parent240c77918bbcf0d5f67799916b808b8a65d434c5 (diff)
downloadFreeBSD-src-6678cf7c2ac8c768ea5efe9fe0392f07e522c963.zip
FreeBSD-src-6678cf7c2ac8c768ea5efe9fe0392f07e522c963.tar.gz
Import file version 4.23 onto the vendor branch
Diffstat (limited to 'contrib/file/softmagic.c')
-rw-r--r--contrib/file/softmagic.c207
1 files changed, 195 insertions, 12 deletions
diff --git a/contrib/file/softmagic.c b/contrib/file/softmagic.c
index e37517c..21a0148 100644
--- a/contrib/file/softmagic.c
+++ b/contrib/file/softmagic.c
@@ -38,7 +38,7 @@
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.99 2007/05/08 14:44:18 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.103 2007/12/27 16:35:59 christos Exp $")
#endif /* lint */
private int match(struct magic_set *, struct magic *, uint32_t,
@@ -254,9 +254,10 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break;
}
}
- firstline = 0;
- if (printed_something)
+ if (printed_something) {
+ firstline = 0;
returnval = 1;
+ }
if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {
return 1; /* don't keep searching */
}
@@ -310,6 +311,8 @@ private int32_t
mprint(struct magic_set *ms, struct magic *m)
{
uint64_t v;
+ float vf;
+ double vd;
int64_t t = 0;
char buf[512];
union VALUETYPE *p = &ms->ms_value;
@@ -398,11 +401,8 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset + m->vallen;
}
else {
- if (*m->value.s == '\0') {
- char *cp = strchr(p->s,'\n');
- if (cp)
- *cp = '\0';
- }
+ if (*m->value.s == '\0')
+ p->s[strcspn(p->s, "\n")] = '\0';
if (file_printf(ms, m->desc, p->s) == -1)
return -1;
t = ms->offset + strlen(p->s);
@@ -445,6 +445,48 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset + sizeof(uint64_t);
break;
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
+ vf = p->f;
+ switch (check_fmt(ms, m)) {
+ case -1:
+ return -1;
+ case 1:
+ if (snprintf(buf, sizeof(buf), "%g", vf) < 0)
+ return -1;
+ if (file_printf(ms, m->desc, buf) == -1)
+ return -1;
+ break;
+ default:
+ if (file_printf(ms, m->desc, vf) == -1)
+ return -1;
+ break;
+ }
+ t = ms->offset + sizeof(float);
+ break;
+
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ vd = p->d;
+ switch (check_fmt(ms, m)) {
+ case -1:
+ return -1;
+ case 1:
+ if (snprintf(buf, sizeof(buf), "%g", vd) < 0)
+ return -1;
+ if (file_printf(ms, m->desc, buf) == -1)
+ return -1;
+ break;
+ default:
+ if (file_printf(ms, m->desc, vd) == -1)
+ return -1;
+ break;
+ }
+ t = ms->offset + sizeof(double);
+ break;
+
case FILE_REGEX: {
char *cp;
int rval;
@@ -545,6 +587,35 @@ cvt_64(union VALUETYPE *p, const struct magic *m)
DO_CVT(q, (uint64_t));
}
+#define DO_CVT2(fld, cast) \
+ if (m->num_mask) \
+ switch (m->mask_op & FILE_OPS_MASK) { \
+ case FILE_OPADD: \
+ p->fld += cast m->num_mask; \
+ break; \
+ case FILE_OPMINUS: \
+ p->fld -= cast m->num_mask; \
+ break; \
+ case FILE_OPMULTIPLY: \
+ p->fld *= cast m->num_mask; \
+ break; \
+ case FILE_OPDIVIDE: \
+ p->fld /= cast m->num_mask; \
+ break; \
+ } \
+
+private void
+cvt_float(union VALUETYPE *p, const struct magic *m)
+{
+ DO_CVT2(f, (float));
+}
+
+private void
+cvt_double(union VALUETYPE *p, const struct magic *m)
+{
+ DO_CVT2(d, (double));
+}
+
/*
* Convert the byte order of the data we are looking at
* While we're here, let's apply the mask operation
@@ -644,6 +715,36 @@ mconvert(struct magic_set *ms, struct magic *m)
((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2]));
cvt_32(p, m);
return 1;
+ case FILE_FLOAT:
+ cvt_float(p, m);
+ return 1;
+ case FILE_BEFLOAT:
+ p->l = ((uint32_t)p->hl[0]<<24)|((uint32_t)p->hl[1]<<16)|
+ ((uint32_t)p->hl[2]<<8) |((uint32_t)p->hl[3]);
+ cvt_float(p, m);
+ return 1;
+ case FILE_LEFLOAT:
+ p->l = ((uint32_t)p->hl[3]<<24)|((uint32_t)p->hl[2]<<16)|
+ ((uint32_t)p->hl[1]<<8) |((uint32_t)p->hl[0]);
+ cvt_float(p, m);
+ return 1;
+ case FILE_DOUBLE:
+ cvt_double(p, m);
+ return 1;
+ case FILE_BEDOUBLE:
+ p->q = ((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
+ ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
+ ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)|
+ ((uint64_t)p->hq[6]<<8) |((uint64_t)p->hq[7]);
+ cvt_double(p, m);
+ return 1;
+ case FILE_LEDOUBLE:
+ p->q = ((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
+ ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
+ ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)|
+ ((uint64_t)p->hq[1]<<8) |((uint64_t)p->hq[0]);
+ cvt_double(p, m);
+ return 1;
case FILE_REGEX:
case FILE_SEARCH:
case FILE_DEFAULT:
@@ -730,13 +831,17 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
offset);
return -1;
}
- for (/*EMPTY*/; src < esrc; src++, dst++) {
+ for (/*EMPTY*/; src < esrc; src += 2, dst++) {
if (dst < edst)
- *dst = *src++;
+ *dst = *src;
else
break;
- if (*dst == '\0')
- *dst = ' ';
+ if (*dst == '\0') {
+ if (type == FILE_BESTRING16 ?
+ *(src - 1) != '\0' :
+ *(src + 1) != '\0')
+ *dst = ' ';
+ }
}
*edst = '\0';
return 0;
@@ -1289,10 +1394,20 @@ mget(struct magic_set *ms, const unsigned char *s,
case FILE_BELDATE:
case FILE_LELDATE:
case FILE_MELDATE:
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
if (nbytes < (offset + 4))
return 0;
break;
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ if (nbytes < (offset + 8))
+ return 0;
+ break;
+
case FILE_STRING:
case FILE_PSTRING:
case FILE_SEARCH:
@@ -1395,6 +1510,8 @@ magiccheck(struct magic_set *ms, struct magic *m)
{
uint64_t l = m->value.q;
uint64_t v;
+ float fl, fv;
+ double dl, dv;
int matched;
union VALUETYPE *p = &ms->ms_value;
@@ -1436,6 +1553,72 @@ magiccheck(struct magic_set *ms, struct magic *m)
v = p->q;
break;
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
+ fl = m->value.f;
+ fv = p->f;
+ switch (m->reln) {
+ case 'x':
+ matched = 1;
+ break;
+
+ case '!':
+ matched = fv != fl;
+ break;
+
+ case '=':
+ matched = fv == fl;
+ break;
+
+ case '>':
+ matched = fv > fl;
+ break;
+
+ case '<':
+ matched = fv < fl;
+ break;
+
+ default:
+ matched = 0;
+ file_magerror(ms, "cannot happen with float: invalid relation `%c'", m->reln);
+ return -1;
+ }
+ return matched;
+
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ dl = m->value.d;
+ dv = p->d;
+ switch (m->reln) {
+ case 'x':
+ matched = 1;
+ break;
+
+ case '!':
+ matched = dv != dl;
+ break;
+
+ case '=':
+ matched = dv == dl;
+ break;
+
+ case '>':
+ matched = dv > dl;
+ break;
+
+ case '<':
+ matched = dv < dl;
+ break;
+
+ default:
+ matched = 0;
+ file_magerror(ms, "cannot happen with double: invalid relation `%c'", m->reln);
+ return -1;
+ }
+ return matched;
+
case FILE_DEFAULT:
l = 0;
v = 0;
OpenPOWER on IntegriCloud