#endif
#ifndef lint
-FILE_RCSID("@(#)$Id: apprentice.c,v 1.98 2006/10/31 19:37:17 christos Exp $")
+FILE_RCSID("@(#)$Id: apprentice.c,v 1.99 2006/12/08 20:31:07 christos Exp $")
#endif /* lint */
#define EATAB {while (isascii((unsigned char) *l) && \
private const char *getstr(struct magic_set *, const char *, char *, int,
int *);
private int parse(struct magic_set *, struct magic_entry **, uint32_t *,
- const char *, int);
+ const char *, size_t, int);
private void eatsize(const char **);
private int apprentice_1(struct magic_set *, const char *, int, struct mlist *);
private size_t apprentice_magic_strength(const struct magic *);
apprentice_magic_strength(const struct magic *m)
{
#define MULT 10
+ size_t val = 2 * MULT; /* baseline strength */
switch (m->type) {
case FILE_BYTE:
- return 1 * MULT;
+ val += 1 * MULT;
+ break;
case FILE_SHORT:
case FILE_LESHORT:
case FILE_BESHORT:
- return 2 * MULT;
+ val += 2 * MULT;
+ break;
case FILE_LONG:
case FILE_LELONG:
case FILE_BELONG:
case FILE_MELONG:
- return 4 * MULT;
+ val += 4 * MULT;
+ break;
case FILE_PSTRING:
case FILE_STRING:
- return m->vallen * MULT;
+ val += m->vallen * MULT;
+ break;
case FILE_BESTRING16:
case FILE_LESTRING16:
- return m->vallen * MULT / 2;
+ val += m->vallen * MULT / 2;
+ break;
case FILE_SEARCH:
case FILE_REGEX:
- return m->vallen;
+ val += m->vallen;
+ break;
case FILE_DATE:
case FILE_LEDATE:
case FILE_LELDATE:
case FILE_BELDATE:
case FILE_MELDATE:
- return 4 * MULT;
+ val += 4 * MULT;
+ break;
case FILE_QDATE:
case FILE_LEQDATE:
case FILE_QLDATE:
case FILE_LEQLDATE:
case FILE_BEQLDATE:
- return 8 * MULT;
+ val += 8 * MULT;
+ break;
default:
- return 0;
+ val = 0;
+ (void)fprintf(stderr, "Bad type %d\n", m->type);
+ abort();
+ }
+
+ switch (m->reln) {
+ case 'x': /* matches anything penalize */
+ val = 0;
+ break;
+
+ case '!':
+ case '=': /* Exact match, prefer */
+ val += MULT;
+ break;
+
+ case '>':
+ case '<': /* comparison match reduce strength */
+ val -= 2 * MULT;
+ break;
+
+ case '^':
+ case '&': /* masking bits, we could count them too */
+ val -= MULT;
+ break;
+
+ default:
+ (void)fprintf(stderr, "Bad relation %c\n", m->reln);
+ abort();
}
+ return val;
}
/*
int errs = 0;
struct magic_entry *marray;
uint32_t marraycount, i, mentrycount = 0;
+ size_t lineno = 0;
ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */
/* read and parse this file */
for (ms->line = 1; fgets(line, BUFSIZ, f) != NULL; ms->line++) {
size_t len;
- if (line[0] == '#') /* comment, do not parse */
- continue;
len = strlen(line);
- if (len < 2) /* null line, garbage, etc */
+ if (len == 0) /* null line, garbage, etc */
continue;
- if (line[len - 1] == '\n')
+ if (line[len - 1] == '\n') {
+ lineno++;
line[len - 1] = '\0'; /* delete newline */
- if (parse(ms, &marray, &marraycount, line, action) != 0)
+ }
+ if (line[0] == '\0') /* empty, do not parse */
+ continue;
+ if (line[0] == '#') /* comment, do not parse */
+ continue;
+ if (parse(ms, &marray, &marraycount, line, lineno, action) != 0)
errs++;
}
*/
private int
parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
- const char *line, int action)
+ const char *line, size_t lineno, int action)
{
size_t i;
struct magic_entry *me;
m->cont_level = 0;
me->cont_count = 1;
}
+ m->lineno = lineno;
if (m->cont_level != 0 && *l == '&') {
++l; /* step over */
*/
/*
* file.h - definitions for file(1) program
- * @(#)$Id: file.h,v 1.81 2006/11/25 17:28:54 christos Exp $
+ * @(#)$Id: file.h,v 1.82 2006/12/08 20:31:07 christos Exp $
*/
#ifndef __file_h__
/* Word 5 */
int32_t in_offset; /* offset from indirection */
/* Word 6 */
- uint32_t dummy4;
+ uint32_t lineno; /* line number in magic file */
/* Word 7,8 */
uint64_t mask; /* mask before comparison with value */
/* Words 9-16 */
#include <time.h>
#ifndef lint
-FILE_RCSID("@(#)$Id: print.c,v 1.55 2006/11/01 20:16:43 christos Exp $")
+FILE_RCSID("@(#)$Id: print.c,v 1.56 2006/12/08 20:31:07 christos Exp $")
#endif /* lint */
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
{
private const char optyp[] = { FILE_OPS };
- (void) fputc('[', stderr);
+ (void) fprintf(stderr, "[%zu", m->lineno);
(void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7),
m->offset);
#ifndef lint
-FILE_RCSID("@(#)$Id: softmagic.c,v 1.85 2006/11/25 17:28:54 christos Exp $")
+FILE_RCSID("@(#)$Id: softmagic.c,v 1.86 2006/12/08 20:31:07 christos Exp $")
#endif /* lint */
private int match(struct magic_set *, struct magic *, uint32_t,
file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
{
struct mlist *ml;
+ int rv;
for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next)
- if (match(ms, ml->magic, ml->nmagic, buf, nbytes))
- return 1;
+ if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes)) != 0)
+ return rv;
return 0;
}
int32_t oldoff = 0;
int returnval = 0; /* if a match is found it is set to 1*/
int firstline = 1; /* a flag to print X\n X\n- X */
+ int printed_something = 0;
if (check_mem(ms, cont_level) == -1)
return -1;
int flush = !mget(ms, &p, s, &magic[magindex], nbytes,
cont_level);
if (flush) {
- if (magic[magindex].reln == '!') flush = 0;
+ if (magic[magindex].reln == '!')
+ flush = 0;
} else {
switch (magiccheck(ms, &p, &magic[magindex])) {
case -1:
*/
if (magic[magindex].desc[0]) {
need_separator = 1;
+ printed_something = 1;
if (print_sep(ms, firstline) == -1)
return -1;
}
* make sure that we have a separator first.
*/
if (magic[magindex].desc[0]) {
+ printed_something = 1;
if (print_sep(ms, firstline) == -1)
return -1;
}
}
}
firstline = 0;
- returnval = 1;
- if ((ms->flags & MAGIC_CONTINUE) == 0) {
+ if (printed_something)
+ returnval = 1;
+ if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {
return 1; /* don't keep searching */
}
}
case -1:
return -1;
case 1:
- if (snprintf(buf, sizeof(buf), "%hu", (unsigned short)v) < 0)
+ if (snprintf(buf, sizeof(buf), "%hu",
+ (unsigned short)v) < 0)
return -1;
if (file_printf(ms, m->desc, buf) == -1)
return -1;
ms->offset += range - 1;
break;
}
- if (range + slen >= p->search.buflen)
+ if (range + slen >= p->search.buflen) {
+ v = 1;
break;
+ }
len = slen;
a = (unsigned char*)m->value.s;
b = (unsigned char*)p->search.buf + range;
}
free(p->search.buf);
p->search.buf = NULL;
+ if (v)
+ return 0;
break;
}
default: