diff options
Diffstat (limited to 'usr.bin/file/apprentice.c')
-rw-r--r-- | usr.bin/file/apprentice.c | 125 |
1 files changed, 98 insertions, 27 deletions
diff --git a/usr.bin/file/apprentice.c b/usr.bin/file/apprentice.c index e1b4f45..d637399 100644 --- a/usr.bin/file/apprentice.c +++ b/usr.bin/file/apprentice.c @@ -29,56 +29,92 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <errno.h> #include "file.h" #ifndef lint static char *moduleid = - "@(#)$Id: apprentice.c,v 1.19 1994/05/03 17:58:23 christos Exp $"; + "@(#)$Id: apprentice.c,v 1.23 1995/10/27 23:12:01 christos Exp $"; #endif /* lint */ #define EATAB {while (isascii((unsigned char) *l) && \ isspace((unsigned char) *l)) ++l;} +#define LOWCASE(l) (isupper((unsigned char) (l)) ? \ + tolower((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 void eatsize __P((char **)); static int maxmagic = 0; +static int apprentice_1 __P((char *, int)); + int apprentice(fn, check) -char *fn; /* name of magic file */ +char *fn; /* list of magic files */ int check; /* non-zero? checking-only run. */ { - FILE *f; - char line[BUFSIZ+1]; - int errs = 0; - - f = fopen(fn, "r"); - if (f==NULL) { - (void) fprintf(stderr, "%s: can't read magic file %s\n", - progname, fn); - if (check) - return -1; - else - exit(1); - } + char *p, *mfn; + int file_err, errs = -1; maxmagic = MAXMAGIS; - if ((magic = (struct magic *) calloc(sizeof(struct magic), maxmagic)) - == NULL) { + magic = (struct magic *) calloc(sizeof(struct magic), maxmagic); + mfn = malloc(strlen(fn)+1); + if (magic == NULL || mfn == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); if (check) return -1; else exit(1); } + fn = strcpy(mfn, fn); + while (fn) { + p = strchr(fn, ':'); + if (p) + *p++ = '\0'; + file_err = apprentice_1(fn, check); + if (file_err > errs) + errs = file_err; + fn = p; + } + if (errs == -1) + (void) fprintf(stderr, "%s: couldn't find any magic files!\n", + progname); + if (!check && errs) + exit(1); + + free(mfn); + return errs; +} + +static int +apprentice_1(fn, check) +char *fn; /* name of magic file */ +int check; /* non-zero? checking-only run. */ +{ + static const char hdr[] = + "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"; + FILE *f; + char line[BUFSIZ+1]; + int errs = 0; + + f = fopen(fn, "r"); + if (f==NULL) { + if (errno != ENOENT) + (void) fprintf(stderr, + "%s: can't read magic file %s (%s)\n", + progname, fn, strerror(errno)); + return -1; + } + /* parse it */ if (check) /* print silly verbose header for USG compat. */ - (void) printf("cont\toffset\ttype\topcode\tmask\tvalue\tdesc\n"); + (void) printf("%s\n", hdr); for (lineno = 1;fgets(line, BUFSIZ, f) != NULL; lineno++) { if (line[0]=='#') /* comment, do not parse */ @@ -87,11 +123,11 @@ int check; /* non-zero? checking-only run. */ continue; line[strlen(line)-1] = '\0'; /* delete newline */ if (parse(line, &nmagic, check) != 0) - ++errs; + errs = 1; } (void) fclose(f); - return errs ? -1 : 0; + return errs; } /* @@ -147,8 +183,9 @@ int *ndx, check; struct magic *m; char *t, *s; +#define ALLOC_INCR 20 if (nd+1 >= maxmagic){ - maxmagic += 20; + maxmagic += ALLOC_INCR; if ((magic = (struct magic *) realloc(magic, sizeof(struct magic) * maxmagic)) == NULL) { @@ -158,6 +195,7 @@ int *ndx, check; else exit(1); } + memset(&magic[*ndx], 0, sizeof(struct magic) * ALLOC_INCR); } m = &magic[*ndx]; m->flag = 0; @@ -174,7 +212,7 @@ int *ndx, check; } /* get offset, then skip over it */ - m->offset = (int) strtol(l,&t,0); + m->offset = (int) strtoul(l,&t,0); if (l == t) magwarn("offset %s invalid", l); l = t; @@ -186,13 +224,16 @@ int *ndx, check; * read [.lbs][+-]nnnnn) */ if (*l == '.') { - switch (*++l) { + l++; + switch (LOWCASE(*l)) { case 'l': m->in.type = LONG; break; + case 'h': case 's': m->in.type = SHORT; break; + case 'c': case 'b': m->in.type = BYTE; break; @@ -205,7 +246,7 @@ int *ndx, check; s = l; if (*l == '+' || *l == '-') l++; if (isdigit((unsigned char)*l)) { - m->in.offset = strtol(l, &t, 0); + m->in.offset = strtoul(l, &t, 0); if (*s == '-') m->in.offset = - m->in.offset; } else @@ -278,7 +319,8 @@ int *ndx, check; /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */ if (*l == '&') { ++l; - m->mask = signextend(m, strtol(l, &l, 0)); + m->mask = signextend(m, strtoul(l, &l, 0)); + eatsize(&l); } else m->mask = ~0L; EATAB; @@ -360,8 +402,10 @@ char **p; *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen); m->vallen = slen; } else - if (m->reln != 'x') - m->value.l = signextend(m, strtol(*p, p, 0)); + if (m->reln != 'x') { + m->value.l = signextend(m, strtoul(*p, p, 0)); + eatsize(p); + } return 0; } @@ -549,3 +593,30 @@ int len; } } } + +/* + * eatsize(): Eat the size spec from a number [eg. 10UL] + */ +static void +eatsize(p) +char **p; +{ + char *l = *p; + + if (LOWCASE(*l) == 'u') + l++; + + switch (LOWCASE(*l)) { + case 'l': /* long */ + case 's': /* short */ + case 'h': /* short */ + case 'b': /* char/byte */ + case 'c': /* char/byte */ + l++; + /*FALLTHROUGH*/ + default: + break; + } + + *p = l; +} |