/* * eatsize(): Eat the size spec from a number [eg. 10UL] */ static void eatsize(const char **p) { const 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; }
static int magic_parse(char *p) { struct magic *m; char *t, *s; int i, j; if (Magiccnt + 1 > Magicmax) errx(1, "magic_parse: magic table full"); m = &Magic[Magiccnt]; m->flag = 0; m->cont_level = 0; while (*p == '>') { p++; /* step over */ m->cont_level++; } if (m->cont_level != 0 && *p == '(') { p++; /* step over */ m->flag |= INDIR; } if (m->cont_level != 0 && *p == '&') { p++; /* step over */ m->flag |= ADD; } /* Get offset, then skip over it. */ m->offset = (int) strtoul(p, &t, 0); if (p == t) errx(1, "magic_parse: offset %s invalid", p); p = t; if (m->flag & INDIR) { m->in.type = LONG; m->in.offset = 0; /* read [.lbs][+-]nnnnn) */ if (*p == '.') { p++; switch (LOWCASE(*p)) { 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; default: errx(1, "magic_parse: indirect offset " "type '%c' invalid", *p); break; } p++; } s = p; if (*p == '+' || *p == '-') p++; if (isdigit((u_char) *p)) { m->in.offset = strtoul(p, &t, 0); if (*s == '-') m->in.offset = - m->in.offset; } else t = p; if (*t++ != ')') errx(1, "magic_parse: missing ')' in indirect offset"); p = t; } while (isascii((u_char) *p) && isdigit((u_char) *p)) p++; while (isascii((u_char) *p) && isspace((u_char) *p)) p++; if (*p == 'u') { p++; m->flag |= UNSIGNED; } /* Get type, skip it. */ t = p; for (i = 0; i < 12; i++) { j = strlen(Magictypes[i]); if (strncmp(p, Magictypes[i], j) == 0) { m->type = i + 1; p += j; break; } } if (p == t) errx(1, "magic_parse: type %s invalid", p); /* New-style and'ing: "0 byte&0x80 =0x80 dynamically linked" */ if (*p == '&') { p++; m->mask = signextend(m, strtoul(p, &p, 0)); eatsize(&p); } else m->mask = ~0L; while (isascii((u_char) *p) && isspace((u_char) *p)) p++; switch(*p) { case '>': case '<': /* Old-style and'ing: "0 byte &0x80 dynamically linked" */ case '&': case '^': case '=': m->reln = *p; p++; break; case '!': if (m->type != STRING) { m->reln = *p; p++; break; } /* FALLTHRU */ default: if (*p == 'x' && isascii((u_char) p[1]) && isspace((u_char) p[1])) { m->reln = *p; p++; goto parse_get_desc; /* Bill The Cat */ } m->reln = '='; break; } while (isascii((u_char) *p) && isspace((u_char) *p)) p++; if (getvalue(m, &p)) return (0); parse_get_desc: /* Now get last part - the description. */ while (isascii((u_char) *p) && isspace((u_char) *p)) p++; strlcpy(m->desc, p, sizeof(m->desc)); if (Opt_debug) { mdump(m); } Magiccnt++; return (1); }